情况肯定很奇怪。在某些模糊的情况下,连接偶尔会变得非常缓慢。在我的情况下,正常的TCP数据交换是每个段约10-25 Kbytes有效负载,但有时它会变成每个段约200-500字节。
经过一些故障排除,我意识到其他网络服务无法重现此问题,因此看起来像是我的服务有问题。但我想不出哪里出错了。它在3.10 Linux内核上运行良好,但在4.4上表现出奇怪的行为。这可能是一些内部内核更改导致的问题吗?
我尝试使用Linux sysctl
设置:
net.ipv4.tcp_congestion_control
net.ipv4.tcp_sack
net.ipv4.route.flush
但这并没有帮助。
似乎问题出现在监听套接字的一侧。在 tcpdump 中,TCP 窗口大小在握手时是正常的。但是在第一个传入数据包之后,窗口大小会减小(由监听方)。
UPD 这里是我的服务器端代码片段:
serv_fd = socket(AF_INET, SOCK_STREAM, 0);
if (serv_fd == -1) {
perror("socket");
return;
}
server.sin_family = AF_INET;
server.sin_port = htons(LISTEN_PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
#ifdef SET_BUF
if (setsockopt(serv_fd, SOL_SOCKET, SO_RCVBUF, &buflen, sizeof(int)) == -1) {
perror ("setsockopt");
return;
}
if (setsockopt(serv_fd, SOL_SOCKET, SO_SNDBUF, &buflen, sizeof(int)) == -1) {
perror ("setsockopt");
return;
}
#endif // SET_BUF
if (bind(serv_fd, (struct sockaddr *) &server, sizeof(server)) == -1) {
perror("bind");
return;
}
if (listen(serv_fd, 3)) {
perror("listen");
return;
}
printf("Server is listening on %u\n", LISTEN_PORT);
有人能为我解决问题吗?我将非常感激!
这可能与最近的Linux内核修改有关吗?我需要调整一些Linux内核设置或检查一些用户模式设置(例如套接字选项或其他内容)吗?
P.S. 问题是不稳定的。
更新:
tcpdump的输出:
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [S], seq 426261790, win 43690, options [mss 65495,sackOK,TS val 799180610 ecr 0,nop,wscale 7], length 0
IP 10.0.0.99.12345 > 10.0.0.34.31334: Flags [S.], seq 803872704, ack 426261791, win 65483, options [mss 65495,sackOK,TS val 799180567 ecr 799180610,nop,wscale 0], length 0
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 799180610 ecr 799180567], length 0
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [P.], seq 1:1301, ack 1, win 342, options [nop,nop,TS val 799180610 ecr 799180567], length 1300
IP 10.0.0.34.31334 > 10.0.0.99.12345: Flags [P.], seq 1301:1804, ack 1, win 342, options [nop,nop,TS val 799181412 ecr 799180610], length 503
IP 10.0.0.99.12345 > 10.0.0.34.31334: Flags [.], ack 1804, win 512, options [nop,nop,TS val 799181412 ecr 799181412], length 0
10.0.0.34.31334是客户端,10.0.0.99.12345是服务器。请注意最后一行中意外的win 512
。
更新2: 我在dmesg中看到了几条关于SYN-cookies的消息:
possible SYN flooding on port 12345. Sending cookies.
但它们与慢传输并不那么相关。
dmesg
输出。在传输缓慢的时候有什么异常吗? - red0ctnr_table_entries
,该值的最小值为8+1
,向上舍入为2的幂 =16
。我实际上没有尝试跟踪listen()
中的backlog
值。要真正证明基于backlog
值为3的SYN队列长度为16
需要进行更多的调查。 - JimD.