Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68764
  • 博文数量: 11
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 120
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-06 15:04
文章分类
文章存档

2018年(11)

我的朋友

分类: LINUX

2018-04-07 15:18:38

listen函数只能被SOCK_STREAM类型的服务器调用,listen提供两个功能,
第一当套接字由套接字函数创建时,它被认为是活动的套接字,即将发出连接的客户端套接字。 监听功能将未连接的套接字转换为被动套接字,指示该套接字内核应该接受传入此套接字的连接请求。 在TCP状态转换图的中,调用listen将套接字从CLOSED状态移动到LISTEN状态。
第二listen的第二个参数指定套接字上可以排队等待的连接数的最大值,超过最大值时,套接字将拒绝新的连接请求

内核listen系统调用

点击(此处)折叠或打开

  1. SYSCALL_DEFINE2(listen, int, fd, int, backlog)
  2. {
  3.     struct socket *sock;
  4.     int err, fput_needed;
  5.     int somaxconn;

  6.     sock = sockfd_lookup_light(fd, &err, &fput_needed);
  7.     if (sock) {
  8.         somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
  9.         if ((unsigned int)backlog > somaxconn)
  10.             backlog = somaxconn;

  11.         err = security_socket_listen(sock, backlog);
  12.         if (!err)
  13.             err = sock->ops->listen(sock, backlog);

  14.         fput_light(sock->file, fput_needed);
  15.     }
  16.     return err;
  17. }
调用的是unix_listen

点击(此处)折叠或打开

  1. static int unix_listen(struct socket *sock, int backlog)
  2. {
  3.     int err;
  4.     struct sock *sk = sock->sk;
  5.     struct unix_sock *u = unix_sk(sk);
  6.     struct pid *old_pid = NULL;

  7.     err = -EOPNOTSUPP;
  8.     if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
  9.         goto out;    /* Only stream/seqpacket sockets accept */
  10.     err = -EINVAL;
  11.     if (!u->addr)
  12.         goto out;    /* No listens on an unbound socket */
  13.     unix_state_lock(sk);
  14.     if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
  15.         goto out_unlock;
  16.     if (backlog > sk->sk_max_ack_backlog) //对参数门限进行校验,不能超过上限
  17.         wake_up_interruptible_all(&u->peer_wait);
  18.     sk->sk_max_ack_backlog    = backlog;
  19.     sk->sk_state        = TCP_LISTEN; //改变传输控制块状态
  20.     /* set credentials so connect can copy them */
  21.     init_peercred(sk);
  22.     err = 0;

  23. out_unlock:
  24.     unix_state_unlock(sk);
  25.     put_pid(old_pid);
  26. out:
  27.     return err;
  28. }

进入监听状态之后就可以接收客户端的连接了。


阅读(1879) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~