listen系统调用

Posted Alex

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了listen系统调用相关的知识,希望对你有一定的参考价值。

 

 1 /*
 2  *    Perform a listen. Basically, we allow the protocol to do anything
 3  *    necessary for a listen, and if that works, we mark the socket as
 4  *    ready for listening.
 5  */
 6 
 7 SYSCALL_DEFINE2(listen, int, fd, int, backlog)
 8 {
 9     struct socket *sock;
10     int err, fput_needed;
11     int somaxconn;
12 
13     /* 查找socket结构 */
14     sock = sockfd_lookup_light(fd, &err, &fput_needed);
15     if (sock) {
16         somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
17 
18         /* backlog不能超过设置值 */
19         if ((unsigned int)backlog > somaxconn)
20             backlog = somaxconn;
21 
22         /* 安全模块检查 */
23         err = security_socket_listen(sock, backlog);
24         if (!err)
25             /* 调用具体协议族的listen函数,只有SOCK_STREAM支持listen */
26             err = sock->ops->listen(sock, backlog);
27 
28         fput_light(sock->file, fput_needed);
29     }
30     return err;
31 }

 

 

 1 /*
 2  *    Move a socket into listening state.
 3  */
 4 int inet_listen(struct socket *sock, int backlog)
 5 {
 6     struct sock *sk = sock->sk;
 7     unsigned char old_state;
 8     int err;
 9 
10     lock_sock(sk);
11 
12     err = -EINVAL;
13 
14     /* 检查socket状态和类型,仅支持SOCK_STREAM */
15     if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM)
16         goto out;
17 
18     /* 记录连接当前状态 */
19     old_state = sk->sk_state;
20 
21     /* 检查连接状态,需为close或者listen */
22     if (!((1 << old_state) & (TCPF_CLOSE | TCPF_LISTEN)))
23         goto out;
24 
25     /* Really, if the socket is already in listen state
26      * we can only allow the backlog to be adjusted.
27      */
28     /* 如果尚未listen过 */
29     if (old_state != TCP_LISTEN) {
30         /* Enable TFO w/o requiring TCP_FASTOPEN socket option.
31          * Note that only TCP sockets (SOCK_STREAM) will reach here.
32          * Also fastopen backlog may already been set via the option
33          * because the socket was in TCP_LISTEN state previously but
34          * was shutdown() rather than close().
35          */
36         /* TFO相关*/
37         if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
38             (sysctl_tcp_fastopen & TFO_SERVER_ENABLE) &&
39             !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) {
40             fastopen_queue_tune(sk, backlog);
41             tcp_fastopen_init_key_once(true);
42         }
43 
44         /* 开始监听 */
45         err = inet_csk_listen_start(sk, backlog);
46         if (err)
47             goto out;
48     }
49 
50     /* 设置backlog,包括已经listen过,调整backlog */
51     sk->sk_max_ack_backlog = backlog;
52     err = 0;
53 
54 out:
55     release_sock(sk);
56     return err;
57 }
58 EXPORT_SYMBOL(inet_listen);

 

其中inet_csk_listen_start函数将在阅读tcp代码时详细分析;

 

以上是关于listen系统调用的主要内容,如果未能解决你的问题,请参考以下文章

Python干货socket中的listen()参数(数字)到底代表什么?

listen系统调用

从listen()方法调用一窥Socket与系统调用

Servlet相关 Filter相关 Listener相关

WSA listen() 调用中的 C++ 异常

如何测量代码片段的调用次数和经过时间