Столкнувшись с проблемой с recv () и send () api winsock. Recv () зависает при получении последнего пакета - PullRequest
0 голосов
/ 22 августа 2009

У меня проблема с recv () и send () api winsock. Recv () зависает при получении последнего пакета.

Описание проблемы: -

Приложение системы A записывает данные через неблокирующий сокет, а приложение системы B получает данные через блокирующий сокет кусками по 64 КБ.

Кажется, что при чтении, вероятно, последнего пакета 64 КБ, который может быть меньше или равен 64 КБ, прием зависает. Я не уверен, является ли получение последнего пакета или отправка последнего пакета проблемой, но я периодически наблюдаю эту проблему в наших старых приложениях.

Кто-нибудь сталкивался с подобной проблемой раньше? Если да, то, пожалуйста, предоставьте ваши данные.

Если нет, то не могли бы вы предоставить некоторые методы устранения неполадок, чтобы сузить до основной причины.

Просто для информации у меня есть серверы win2k3.

Спасибо, Варуна

Ответы [ 3 ]

3 голосов
/ 22 августа 2009

Wireshark - отличный инструмент для устранения неполадок сетевого кода. Он точно покажет, какие пакеты входят и выходят из вашего сетевого интерфейса практически в реальном времени.

Что касается вашей конкретной проблемы: вы говорите, что последний кусок данных может быть короче 64 КБ? Если это так, ваш протокол должен включать некоторую информацию о длине сообщения, чтобы получатель знает, сколько данных нужно искать.

1 голос
/ 23 августа 2009

Пара догадок ...

Если вы используете UDP, возможно, один или несколько пакетов отбрасываются в пути (что UDP может делать в любое время). В этом случае ваш получатель может в конечном итоге ждать данных, которые просто никогда не поступят; чтобы исправить это, вам нужно будет либо внедрить какой-либо способ автоматической повторной отправки потерянных данных, либо (если вам не нужны все данные строго), чтобы отправитель уведомил получателя о том, что он закончил передачу, поэтому получатель может также перестать ждать. (конечно, вам нужно будет обработать случай, когда это уведомление также будет удалено ... оно может усложниться, если вы хотите 100% надежности)

Если вы используете TCP, возможно, вы не тщательно проверяете значения, возвращаемые send () на отправляющей стороне? Если вы предполагаете, что send () всегда будет отправлять количество байтов, которые вы запрашивали, вы можете подумать, что send () отправил все байты, хотя на самом деле он отправил только некоторые (или ни одного) из них ... так что отправитель будет считать передачу завершенной, а получатель застрянет в ожидании данных, которые не поступят.

0 голосов
/ 23 августа 2009

Возможно, проблема в том, что сервер отправляет данные по проводам быстрее, чем получатель может их прочитать. Вы можете попробовать увеличить приемный буфер:

int nSocketBuffer = 131072; // 128k
if (setsockopt(m_sSocket,SOL_SOCKET,SO_RCVBUF,(LPCSTR)&nSocketBuffer,sizeof(int)) == SOCKET_ERROR)
{
    // socket error
    return false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...