Моя версия ядра 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-процесс рукопожатия, поскольку аргумент backlog в listen
равен 2 .
Однако, когда я делаю тест, результат будет 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
- это число полных TCP 3-кодов, которые не являются accept()
пользователем. И sk->sk_max_ack_backlog
- это аргумент listen()
Похоже, я выяснил причину, по которой результат равен 3 , а не 2 ,
Но что меня озадачивает, почему он использует >
, а не >=
, чтобы судить, что очередь переполнена? Разве не разумнее использовать >=
?
ядро новой версии (5.0.9) такое же.