2014-09-08 2 views
0

Я использую неблокирующий сокет через библиотеку сокетов, которая обертывает Winsock2 API. Функция WSAAsyncSelect() используется для отправки уведомлений сокета в окно. (Приложение однопоточное).Закрыть сокет без ожидания отправки в suceeed - Winsock2 неблокирующий TCP-сокет

Я пытаюсь достичь следующей цели для открытого клиентского сокета:

  • Отправить окончательное сообщение на сервер
  • Закройте гнездо и уничтожить окно

Я не хочу сделать блокировку ожидания для сервера ACK мое последнее сообщение, так как это вводит еще один момент задержки/неудачи для пользователей моего кода. Это не жизненно важное сообщение для моего протокола, просто приятный.

В настоящее время мой код заканчивается вызовом Winsock2 send(), чтобы отправить окончательное сообщение, а затем звонит closesocket(). Тем не менее, мой TCP поток (как показано на Wireshark), то выглядит следующим образом:

// Calling send(): 
Me -> Host: [PSH, ACK] 

// Calling closesocket(): 
Me -> Host: [FIN, ACK] 

// Just after that: 
Host -> Me: [ACK]  
Host -> Me: [ACK] 
Host -> Me: [ACK] Len=1380 // A response to my sent packet, that I don't care about 
Me -> Host: [RST, ACK] 
Host -> Me: [RST] 
Host -> Me: [PSH, ACK] // Retransmission of that response 
Me -> Host: [RST] 

Итак, есть два RST запросы, отправляемые Windows. Я считаю, что это связано с тем, что сокет получает сообщение после отправки FIN, поэтому он решает, что RST необходим, но тогда хост интерпретирует это как запрос повторной передачи.

Если я изменить код, чтобы немного подождать, прежде чем вызывать closesocket, то след выглядит совсем иначе: мой конец просто посылает [FIN, ACK], а другой конец посылает [FIN, ACK] назад и нет РЭК.

Мой вопрос: как я могу аккуратно отключить мой сокет (т. Е. Избегать обмена RST) без блокировки?

+0

Я не уверен, что понимаю; поскольку это неблокирующий сокет, почему окончательное чтение должно быть прочитано блокировкой? –

+0

@HarryJohnston Я уничтожаю модальное окно, которое отправляет уведомления сокета, поэтому невозможно сделать неблокирующее чтение –

+0

Ah. Не могли бы вы скрыть окно и уничтожить его после того, как соединение было чисто закрыто? –

ответ

1

Я не хочу, чтобы блокирование ожидало, что сервер выполнит мое последнее сообщение, поскольку это вводит еще один момент задержки/отказа пользователям моего кода. Это не жизненно важное сообщение для моего протокола, просто приятный.

Я предполагаю, что вы говорите об ACK на уровне приложений. Непрочитанные данные вызовут RST отправителю, если вы закроете его до его прибытия. Вы должны решить это. Либо это в протоколе, либо нет.

+0

Я говорю о TCP ACK. Если есть перегрузка сети, это может быть медленным при прибытии, и я не хочу, чтобы мой пользовательский интерфейс должен был ждать, если сеть будет медленной или будет работать во время этой операции. –

+0

Вы говорите, что единственными параметрами являются: (a) ожидание пакета ответа перед закрытием сокета или (b) закрытие сокета и наличие RST? –

+0

Тогда я не знаю, о чем вы говорите. Вы не можете «блокировать ожидания для сервера, чтобы« ACK »мое последнее сообщение», или «дождаться пакета ответа» каким-либо образом. У вас нет API, который делает это.API дает вам нулевую видимость 'ACKs.' Вы можете просто отправить и закрыть. RST обычно провоцируются непрочитанными * данными приложения *. Например, с «Лен = 1380», о котором вы, кажется, забыли. – EJP