Я написал клиент-сервер в пользовательском режиме c приложение на основе сокетов Беркли, которые взаимодействуют через какую-то частную сеть.
Ситуация определенно странная. Иногда связь становится очень медленной при некоторых неопределенных обстоятельствах. Обычный обмен данными по TCP в моем случае составляет около 10-25 Кбайт полезной нагрузки на сегмент, но иногда он становится примерно ~ 200-500 байт на сегмент.
После некоторого устранения неполадок я понял, что эта проблема не воспроизводится для другие сетевые сервисы, таким образом, похоже, что мой сервис виноват. Но я не могу понять, что не так. Он хорошо работал на ядре 3.10 Linux, но странное поведение на 4.4. Могли ли быть какие-то внутренние изменения в ядре, которые вызвали такую проблему?
Я пытался поиграть с настройками Linux sysctl
:
net.ipv4.tcp_congestion_control
net.ipv4.tcp_sack
net.ipv4.route.flush
, но это не помогло help.
Кажется, что проблема появляется на стороне прослушивающего сокета . В 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 или проверять некоторые настройки пользовательского режима (например, параметры сокета или что-то еще)?
PS Проблема нестабильна.
UPD:
Вывод 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
в последней строке.
UPD2: Я видел несколько сообщений о SYN-куки в dmesg, например:
possible SYN flooding on port 12345. Sending cookies.
Но они не так уж связаны с медленным передачи.