Почему сокет TCP отправляет пакет RST вместо повторной отправки данных, когда получает неверный ACK?

Одна из «крутых» вещей в соединениях TPC заключается в том, что данные не теряются. Когда данные не подтверждены, TCP предположительно повторно отправляет данные.

У меня есть классический игровой сервер, написанный на c ++, а клиент написан на Flash AS3.

В клиенте я добавил инструмент проверки, который пытается подключиться к YouTube и Twitter каждые X секунд с таймаутом в 5 секунд. Проблема заключается в том, что после разрыва интернет-соединения клиента в течение нескольких секунд (интернет-контролер получает 1 или 2 таймаута, но после этого получает ОК), он начинает получать данные с сервера, но сервер прекращает прием данных от клиента.

Это поток, полученный TCPDUMP:

1. server > client: Flags [P.], seq 2374:2378, ack 119, win 14600, length 4
2. client > server: Flags [.], ack 2374, win 15524, length 0
3. client > server: Flags [.], ack 2378, win 15520, length 0
. [Here the client sends data to the server, but the server never receives it...]
4. server > client: Flags [P.], seq 2378:2383, ack 119, win 14600, length 5
5. server > client: Flags [P.], seq 2386:2389, ack 119, win 14600, length 3
6. client > server: Flags [.], ack 2386, win 15512, length 0
7. client > server: Flags [.], ack 2389, win 15509, length 0
8. client > server: Flags [R.], seq 127, ack 2389, win 0, length 0

Как вы можете прочитать, когда сервер отправляет данные с неправильным ACK, клиент не отправляет данные повторно, отправляет пакет RST (заставляя сервер закрыть соединение). В журнале клиента я вижу, что получает и обрабатывает данные, отправленные сервером (поэтому соединение не закрывается, когда сервер отправляет неверный ACK).

Когда TCP решает отправить пакет RST вместо повторной отправки данных после получения неверного ACK?

Клиентский сокет — это AS3 Socket определено так:

var socket:Socket = new Socket();

И сокет сервера установлен неблокирующим с fcntl(), Также есть следующие опции:

setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&dummyint, sizeof(int));
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&dummyint, sizeof(int));

3

Решение

Обратите внимание, что, похоже, в дампе отсутствует дополнительный пакет, серверные байты 2383-2385, хотя кажется, что клиент их видел, потому что он их подтвердил.

Сервер не отвечает с неправильным ACK. Он отвечает ACK последнего номера байта, который он видел в потоке, # 119. Клиент должен повторно передать эти пропущенные байты, когда серверу не удается подтвердить их через некоторое время. Вместо этого он отправляет RST.

Нет информации о времени, но я должен был бы предположить, что RST приходит от тайм-аута на клиенте до того, как информация должна была быть повторно передана.

4

Другие решения

TCP не «нестабилен» сам по себе, это протокол. Если что-то нестабильно, это ваше сетевое соединение. TCP имеет алгоритм для повторной попытки в нестабильных сетях. Также возможно, что с вашим кодом что-то не так, и возможно, что промежуточное устройство блокирует ваше соединение.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector