2012-05-10 4 views
5

У меня очень неприятная проблема, которую я нашел несколько раз на других форумах, но я не могу найти правильное решение. Проблема recv() возвращает 0 в последних нескольких байтах соединения. Вот некоторая справочная информация.recv() возвращает 0

  • Оба приложения (клиент/сервер) работают на одном компьютере.
  • Обе (клиент/сервер) сокеты неблокируются
  • Размер передаваемых данных составляет 53 байта.
  • Оба (клиент/сервер) выключения вызова и closesocket, когда был выполнен последний запрос send()/recv().
  • Я также попытался с SO_LINGER и 10 секунд, не имел успеха ни

Я посыл вызова() несколько раз (мелкие куски) и со стороны клиента 53 байта перетекает. Сервер вызывает recv() несколько раз (4 байтовых запроса) и считывает 49 байтов, а затем возвращает 0 (54 байта - 49 байт, поэтому не хватает 4 байта).

MSDN и некоторые форумах пишут для не-блокирующих сокетов:

  • Recv() определенно возвращает < 0 на ошибки и ERRNO/WSAGetLastError устанавливается
  • Recv() определенно возвращает = 0, когда другая сторона закрыл соединение
  • ПРИЕМ() определенно возвращает> 0, когда данные читались

MSDN также говорит:

Использование функций закрытия или выключения с SD_SEND или SD_BOTH приводит к отправке сигнала RELEASE по каналу управления. Должно быть, для использования банкоматом отдельных каналов передачи данных и данных, возможно, что сигнал RELEASE может достичь удаленного конца до того, как последний из достигнет своего пункта назначения, что приведет к потере этих данных. Одним из возможных решений является программирование достаточной задержки между последними отправленными данными и вызовом функции closesocket или shutdown для сокета ATM .

Это рассматривается на примере RECV() и отправить(): http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx

Но до сих пор нет успеха, я до сих пор получить некоторые прерывания в 10% всех соединений после 49 байт получено, 90 % соединений выполнено успешно. Есть идеи? Спасибо.

+0

Я подозреваю, что вы делаете один из нескольких классических ошибок при программировании сокетов.У меня есть несколько идей, но сначала я хочу увидеть ваш код, прежде чем что-то писать. – selbie

ответ

9

recv() возвращает 0 только тогда, когда вы запрашиваете 0-байтовый буфер, или другой одноранговый узел изящно отключен. Если вы не получаете все данные, которые ожидаете, то вы не читаете данные правильно для начала. Обновите свой вопрос с помощью своего фактического кода.

0

Я предполагаю, что вы действительно не отправляете все данные, которые, по вашему мнению, отправляют. Проверьте:

The Ultimate SO_LINGER page