我的linux内核版本是4.4.0。
这是我的代码段
int listenfd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(50001);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 2); // just listen, never accept
while(1)
{
sleep(1);
}
我希望它只能完成 2 个TCP 3-握手过程,因为listen
中的 backlog 参数为 2 。< / p>
但是,当我进行测试时,结果是 3 而不是 2
所以,我看了一下源代码。
在tcp_input.c
int tcp_conn_request(struct request_sock_ops *rsk_ops,
const struct tcp_request_sock_ops *af_ops,
struct sock *sk, struct sk_buff *skb)
{
// code omitted
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
goto drop;
}
// code omitted
}
它使用sk_acceptq_is_full
来查看接受队列是否已满
static inline bool sk_acceptq_is_full(const struct sock *sk)
{
return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
我知道sk->sk_ack_backlog
是用户没有accept()
的完整TCP 3握手的数量。sk->sk_max_ack_backlog
的参数是listen()
所以看来我发现了为什么结果是 3 而不是 2 的原因,
但是令我感到困惑的是,为什么他使用>
而不是>=
来判断队列已满?使用>=
更加合理吗?
新版本(5.0.9)内核相同。