为什么socket.listen的backlog参数比实际少1
在2.6中backlog最少是1,在2.7之后,backlog最少是0,设为0时,socket等待队列却能容纳1个连接,这是为什么? 帮顶 LZ应该知道backlog是干啥用的哦(如不清楚可百度)LWIP的代码如下,linux的没查,
lpcb->backlog = (backlog ? backlog : 1);
回复 3# ilex
backlog为0的时候,等待队列可以有1个客户连接,backlog为1的时候,等待队列可以容纳2个连接,这和backlog作用不符呀?python2.6的时候backlog最低为1,python2.7就改成最低为0了,2.7的changelog里面也没找到相关的详细说明 说实话,从没看过linux的内核代码,
特意查了一下linux有关backlog的代码,我猜和下面有关:
A、处理收到的connect请求:
static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
line1067 if (unix_recvq_full(other)) {
校验backlog失败,报错;
}
}
B:校验队列是否超过backlog
static inline int unix_recvq_full(struct sock const *sk)
{
return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
}
——这个函数看起来是比较sk_receive_queue队列的长度和socket设置的backlog值,用的是>而不是>=
C:sk_receive_queue队列在如下增长:
line 1156
/* take ten and and send info to listening sock */
spin_lock(&other->sk_receive_queue.lock);
__skb_queue_tail(&other->sk_receive_queue, skb);
spin_unlock(&other->sk_receive_queue.lock);
unix_state_unlock(other);
other->sk_data_ready(other, 0);
sock_put(other);
return 0;
3、上面两处行号,是在af_unix.c文件中。
也就是说:先看队列满(超)了没,再入队列。
当设置为1时,
收到第一个sync,看到队列有0个,此时没超,入队列,队列长==1。
再收到一个sync,看到队列有1个,此时没超,入队列,队列长==2。
4、对于设置backlog==0,就先不讨论了,可以试一下设置为1时:c/c++是什么效果,和python是否一样的效果?
看起来和python无关,倒是操作系统/TCPIP相关的问题吧?
linux文件太多,不知道从哪看起,根据感觉在sourcinsight瞎猜的,说错了别笑话。。。 好像找错了代码,感觉和下面几个函数有关:
static inline void sk_acceptq_added(struct sock *sk)
{
sk->sk_ack_backlog++;
}
static inline int sk_acceptq_is_full(struct sock *sk)
{
return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
太晚了,以后再找。 刚看了一下,猜测和上面2个函数有关,
/*
* Process an incoming packet for SYN_RECV sockets represented
* as a request_sock.
*/
struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
struct request_sock *req,
struct request_sock **prev)
{
}
tcp_check_req【先】调用
child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb,
req, NULL);
在->syn_recv_sock里面调用sk_acceptq_is_full(struct sock *sk),检查是否超过了backlog
tcp_check_req【再】调用inet_csk_reqsk_queue_add(sk, req, child);,把SYN挂到链表中。
这个问题跟python 本身没关系, 是linux内核实现的问题,就是楼上说的原因,是sk_acceptq_is_full的问题,
sk->sk_max_ack_backlog就是listen设置的backlog值,sk->sk_ack_backlog是当前backlog长度,
注意他用的是大于比较,就是说等于的时候他不认为是full的,还会继续接受链接,因此用netstat看到的最大连接数永远是backlog+1。
其实这是linux内核的小bug,不过没什么大问题。
页:
[1]