Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> send возвращает ошибку, но код ошибки 0 
V
    Опции темы
Alexeis
Дата 27.9.2011, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 1
Всего: 459



Соединение активно, TCP/IP клиентский сокет в режиме блокировки. Передает блоки по 4кб. После передачи ~20кб данных функция send неожиданно выдает результат -1, т.е. SOCKET_ERROR, но когда смотрим WSAGetLastError() , то код ошибки 0, т.е. успех  smile . Так есть ошибка или нет?

Код

    WSASetLastError(0);
    int len = send(sock, Buffer, Len, 0);
    if (len == SOCKET_ERROR) 
           {
            int r = WSAGetLastError();
            String s = SysErrorMessage(r);
...


Опытным путем было установлено, что если слать данные серверу реже, то ошибка не возникает. Отсюда возникло предположение о том, что переполняется либо буфер отправки клиента, либо буфер приема сервера, но в этом случае WSAGetLastError не должен возвращать успех. Вообще, если не вызывать WSASetLastError(0); то код ошибки получается от вызова другой функции, т.е. функция send вообще не устанавливает код ошибки, так как будто ошибка и не происходила вовсе (так описано в документации по send). 
  Все таки ошибка была или нет? А если была, то как узнать ее описание?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 27.9.2011, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 1
Всего: 459



В чем причина отсутствия кода ошибки узнать не удалось, но предполагая что ошибка таки WSAENOBUFS, использовав статью http://support.microsoft.com/kb/201213/en-us , удалось избавиться от появления ошибки. 
Фактически я отключил буферизацию сокета на отправку
Код

    int val = 0;
    setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&val, sizeof(val));

Вероятнее всего дело было в переполнении буфера отправки. Нет буфера, нет переполнения smile .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Олег2005
Дата 27.9.2011, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Странно, почему вы использовали третий способ:
    Use the socket in nonblocking or asynchronous mode.
    Break large-size data blocks into small ones and specify a relatively small buffer in send for blocking sockets, preferably no larger than 64K.
    Set the SO_SNDBUF socket option to 0 (zero) to allow the stack to send from your application buffer directly.

Цитата

Передает блоки по 4кб. После передачи ~20кб данных функция send неожиданно выдает результат -1, т.е. SOCKET_ERROR, но когда смотрим WSAGetLastError() , то код ошибки 0, т.е. успех. 

Стандартный буфер сокета для TCP в винде - Default: 17520 байт
Вот отсюда и проблемы около 20Кб.
Есть несколько вариантов
посмотреть getsockopt() размер буфера и убедиться, что он достаточен.
Установить больший - если надо.
У вас же передаются блоки по 4 к - это очень мало для переполнения стандартного буфера. 
Единственный вариант - модуль TCP - не может передать в буфер сетевой карты - потому как она еще не отправила предыдущие данные. Это может быть при сильной перегрузке сети.
Во всяком случае не все так очевидно.
Можно еще слать с задержкой - скажем 10 миллисекунд в sleep

Это сообщение отредактировал(а) Олег2005 - 27.9.2011, 20:49
PM MAIL WWW MSN   Вверх
Alexeis
Дата 27.9.2011, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 1
Всего: 459



Цитата(Олег2005 @  27.9.2011,  21:28 Найти цитируемый пост)
Стандартный буфер сокета для TCP в винде - Default: 17520 байт

  Проверял, там размер 8кб, видимо он сравнял его с буфером приема сервера, потому что там тоже 8кб. Это как раз и странно, что успевает отправиться больше чем размер буфера. Загрузки сети ни какой, потому что сервер соединен с клиентом напрямую витой парой. 
>Break large-size data blocks into small ones and specify a relatively small buffer in send for blocking sockets, preferably no larger than 64K
 Так 4Кб как раз и соответствует описанию. Так что тут нечего было менять.

Цитата(Олег2005 @  27.9.2011,  21:28 Найти цитируемый пост)
Можно еще слать с задержкой - скажем 10 миллисекунд в sleep

  Делал, именно так и выяснил. Если задержка 50мс, то нормально отправляется, если 10мс, то успевает переполниться. Однако в режиме с отключенным буфером скорость передачи выше чем с задержкой 50мс. Вообще, не охота играть с таймерами, поскольку задержки по пересылу врядли стабильны во времени. Когда больше, когда меньше. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Олег2005
Дата 27.9.2011, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



В общем проблема понята и решена. smile 
PM MAIL WWW MSN   Вверх
Alexeis
Дата 27.9.2011, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 1
Всего: 459



Цитата(Олег2005 @  27.9.2011,  23:55 Найти цитируемый пост)
В общем проблема понята и решена.

  Не совсем. Меня мучает вопрос, почему код ошибки не возвращается никакой. Слабо вериться что это глюк семерки, пусть даже 64х битной. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1244 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.