10055 WSAENOBUFS: No buffer space available
От: ncode  
Дата: 19.07.07 14:04
Оценка:
В общем виде моя программа отправляет данные приходящие с СОМ порта на сервер (сервер тоже находится в разработке). Используется один клиентский сокет.
Устройство отправляет с CОМ порта данные кусками (размером примерно в 1 килобайт) на сервер. Потом ожидает подтверждения с сервера, затем отправляет следующий кусок и т.д.
Периодически при вызов send() на сокете выдает WSAENOBUFS:

10055 WSAENOBUFS
No buffer space available.
An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

Дальнейшие вызовы send() упорно возвращают WSAENOBUFS. Полный перезапуск моей программы ситуации не меняет.
Что это может быть?
Re: 10055 WSAENOBUFS: No buffer space available
От: Alexander Nechiporuk Россия  
Дата: 19.07.07 15:25
Оценка:
Здравствуйте, ncode, Вы писали:

N>В общем виде моя программа отправляет данные приходящие с СОМ порта на сервер (сервер тоже находится в разработке). Используется один клиентский сокет.

N>Устройство отправляет с CОМ порта данные кусками (размером примерно в 1 килобайт) на сервер. Потом ожидает подтверждения с сервера, затем отправляет следующий кусок и т.д.
N>Периодически при вызов send() на сокете выдает WSAENOBUFS:
N>

N>10055 WSAENOBUFS
N>No buffer space available.
N>An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

N>Дальнейшие вызовы send() упорно возвращают WSAENOBUFS. Полный перезапуск моей программы ситуации не меняет.
N>Что это может быть?

А у тебя случайно МакАффи не стоит? А-то у меня схожая проблема. После часов 20-ти работы происходит такая же фигня, но не в процессе который работает, а в тех которые он запускает. Может в нем что-то где-то течет? больше даже не знаю на что думать...
Re: 10055 WSAENOBUFS: No buffer space available
От: remark Россия http://www.1024cores.net/
Дата: 19.07.07 21:44
Оценка:
Здравствуйте, ncode, Вы писали:

N>Дальнейшие вызовы send() упорно возвращают WSAENOBUFS. Полный перезапуск моей программы ситуации не меняет.

N>Что это может быть?

Возможно закончилась non-paged память ядра, в которой оно выделяет сокетные буферы.
У меня такое было, когда я создавал 120000 активных сокетов.
Попробуй уменьшить размеры буферов на приём и передачу.
И, конечно, убедись, что ничего не течёт.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: 10055 WSAENOBUFS: No buffer space available
От: ncode  
Дата: 20.07.07 05:45
Оценка:
Здравствуйте, remark, Вы писали:
R>Возможно закончилась non-paged память ядра, в которой оно выделяет сокетные буферы.
R>У меня такое было, когда я создавал 120000 активных сокетов.
R>Попробуй уменьшить размеры буферов на приём и передачу.
R>И, конечно, убедись, что ничего не течёт.
Все это конечно проверялось, у меня активный сокет только один (+ те что в системе по умолчанию), память не течет.

У меня вопрос больше по архитектуре сокетов, т.к. в МСДН не описаны некоторые тонкие моменты.
1) Может ли WSAENOBUFS быть связано с сервером? Т.е. сервер не в состоянии принимать данные (перегружен?) и вызов send() у меня завершается с такой ошибкой. Или это связано только с локальными буфферами?
2) Что означает успешный вызов send() на неблокирующем сокете:
— данные записаны в локальный буффер и готовы к отправке?
— или данные отправлены или даже уже получены удаленной стороной?
3) есть ли смысл делать собственную очередь данных на функцию send(), то есть класть куски данных не отправленые send() по причине WSAEWOULDBLOCK (или WSAENOBUFS) в собственный буффер и ждать FD_WRITE события на этом сокете?
Re[3]: 10055 WSAENOBUFS: No buffer space available
От: TarasCo  
Дата: 20.07.07 06:53
Оценка:
N>1) Может ли WSAENOBUFS быть связано с сервером? Т.е. сервер не в состоянии принимать данные (перегружен?) и вызов send() у меня завершается с такой ошибкой. Или это связано только с локальными буфферами?

Только с локальными. Если сервер не смог принять данные по причине собственных ограниченных ресурсов, он не пришлет подтверждение ACK и, возможно, начнет уменьшать окно ( Window ). Все это приведет к согласованному уменьшению скорости передачи. Локальный хост может это ощутить по возвращению WSAEWOULDBLOCK в неблокирующем режиме — это значит буфер данных предназначенных для передачи заполнен и приложение должно ждать его освобождения.
При нормальной работе системы ошибки WSAENOBUFS быть не должно. Кто-то отъел много памяти — либо ваша программа съела всю свою виртуальную память, либо какой-то драйвер ( не ли фаерволов или антивирусов? ) сожрал память ядра.

N>2) Что означает успешный вызов send() на неблокирующем сокете:

N>- данные записаны в локальный буффер и готовы к отправке?
можно сказать так. И нет способа узнать когда они реально будут отправлены. Если соединение аварийно оборвано, нет возможности узнать, сколько данных реально было отправлено.

N>3) есть ли смысл делать собственную очередь данных на функцию send(), то есть класть куски данных не отправленые send() по причине WSAEWOULDBLOCK (или WSAENOBUFS) в собственный буффер и ждать FD_WRITE события на этом сокете?

Это зависит от логики Вашего приложения, от источника данных. В Вашем случае очередь необходима, поскольку нельзя отложить чтение данных из СОМ порта — может переполниться программный буфер драйвера, он не так велик ( 16К по-моему? ). Поэтому необходимо данные вычитывать. Раз сокет не смог отправить данные — их надо где то временно хранить. Вместо очереди можно использовать возможности оси — использовать асинхронную передачу ( overlapped ). В этом случае очередь данных для отправки будет поддерживаться на уровне операционной системы.
Да пребудет с тобою сила
Re: 10055 WSAENOBUFS: No buffer space available
От: NailS Россия  
Дата: 26.07.07 12:00
Оценка:
N>В общем виде моя программа отправляет данные приходящие с СОМ порта на сервер (сервер тоже находится в разработке). Используется один клиентский сокет.
N>Устройство отправляет с CОМ порта данные кусками (размером примерно в 1 килобайт) на сервер. Потом ожидает подтверждения с сервера, затем отправляет следующий кусок и т.д.
N>Периодически при вызов send() на сокете выдает WSAENOBUFS:
N>Дальнейшие вызовы send() упорно возвращают WSAENOBUFS. Полный перезапуск моей программы ситуации не меняет.

Работа ведется по UDP?
Тогда эта ошибка сообщает о том, "что недостаточно места для дейтаграммы или одного из ее фрагментов" (c) Стивенс.
Тогда можно попробовать либо руками дробить данные на более маленькие части, а на сервере склеивать, либо переходить на TCP.
Re: 10055 WSAENOBUFS: No buffer space available
От: hmixa  
Дата: 09.09.07 10:51
Оценка: 9 (1) -1
Здравствуйте, ncode, Вы писали:

N>Периодически при вызов send() на сокете выдает WSAENOBUFS:

N>

N>10055 WSAENOBUFS
N>No buffer space available.
N>An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

N>Дальнейшие вызовы send() упорно возвращают WSAENOBUFS. Полный перезапуск моей программы ситуации не меняет.
N>Что это может быть?

Попробуй сделать вот так — после получения WSA_IO_PENDING дать системе, прокачать информацию. 2 секунды должно хватить, если дольше, то, я думаю, что это сигнал к тому, что что-то не так. Если сокет освободится раньше, то и 2 сек ждать не прийдется, эта функция ждет ровно столько сколько надо.

            hr = WSASend(Socket, pwsaBuff, 1, &dwSent, 0, pOverlapped, (LPWSAOVERLAPPED_COMPLETION_ROUTINE)IoRoutine);
            if (SOCKET_ERROR == hr)
            {
                hr = WSAGetLastError();
                if (WSA_IO_PENDING == hr)
                {
                    hr = SleepEx(2000, TRUE);
                    if (WAIT_IO_COMPLETION != hr)
                    {
                        // поругаться - должно быть все-таки WAIT_IO_COMPLETION, а не S_OK
                    }
                }
                else
                {
                    // поругаться на настоящие ошибки
                }
            }
            SleepEx(0, TRUE); // дать системе вздохнуть (что-бы смогла вызваться IoRoutine), но немного - особо рассиживаться некогда.
Re: Эфемерные порты
От: remark Россия http://www.1024cores.net/
Дата: 19.09.07 16:19
Оценка:
Здравствуйте, ncode, Вы писали:

N>В общем виде моя программа отправляет данные приходящие с СОМ порта на сервер (сервер тоже находится в разработке). Используется один клиентский сокет.

N>Устройство отправляет с CОМ порта данные кусками (размером примерно в 1 килобайт) на сервер. Потом ожидает подтверждения с сервера, затем отправляет следующий кусок и т.д.
N>Периодически при вызов send() на сокете выдает WSAENOBUFS:
N>

N>10055 WSAENOBUFS
N>No buffer space available.
N>An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

N>Дальнейшие вызовы send() упорно возвращают WSAENOBUFS. Полный перезапуск моей программы ситуации не меняет.
N>Что это может быть?


Если клиентские сокеты постоянно создаются и рушатся, то возможно закончились эфемерные порты.
ОС выделяет эфемерные порты из некого диапазона. И после разрушения сокета некоторое время не возвращает порт в пул доступных портов.
Что бы увеличит диапазон надо поменять значение ключа:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort
Плюс:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TCPTimedWaitDelay
что бы изменить задержку перед повторным использованием порта.

Подробности здесь:
http://support.microsoft.com/?id=196271



1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.