LINUX.ORG.RU

Закрытие сокета при неотправленных данных


0

0

Столкнулся с такой проблемой: большое кол-во данных отсылаю в сокет, потом shutdown(sock, SHUT_RDWR); и close(sock); но на приемной стороне приходит только часть данных. Потому что после close они уже теряются на сервере.
Пробовал играться с SO_LINGER - не помогает. теже глюки остаются. Утанавливаемое время не играет роли тоже. Пробовал уже и shutdown убирать. Ничего не помогает.

Сокеты все неблокирующие и крутятся в epoll.
После отсылки делать пауза перед закрытие нет возможности, чтобы у других клиентов не было ожидания большого.
Кто что может подсказать по этому поводу?
P.S. система дебиан x64


поскольку сокет это файловый дескриптор, на него можно сделать sync на отправляющей стороне, а потом уже и закрывать. пробовал так?

Pantserovik ()

Покажи пример кода, на котором это всё вопроизводится.

И пара вопросов к тебе:

  • Смотрел ли ты снифером (tcpdump, wireshark), действительно ли часть данных теряется? А то может проблема в коде на принимающей стороне.
  • Зачем ты используешь shutdown?
Deleted ()
Ответ на: комментарий от Deleted

Данные действтельно теряются. На стороне сервера шлю допустим 100кб и закрываю соедиенение. На стороне клиента снифер показывает что тока часть данных пришла. При том, что клиентсткая часть - это браузер (тестил и под никсы и под вин. везде одинаково).
Ну думал может shutdown поможет чтобы данные не терялись.

Насчет sync - а можно поподробнее? т.е. предлагаешь дял каждого сокета, перед его закрытием делать fsync / fdatasync Мне главное чтобы при этом небыло блокировок.

slesh ()
Ответ на: комментарий от slesh

На стороне сервера шлю допустим 100кб и закрываю соедиенение. На стороне клиента снифер показывает что тока часть данных пришла.

Покажи код.

Deleted ()
Ответ на: комментарий от Deleted

>Покажи код.

Присоединяюсь. Покажи код. Ты точно убедился, что write() вернул то количество байт, которые собирался записать? Может ты даже не записал все данные в сокет.

pathfinder ★★★★ ()
Ответ на: комментарий от pathfinder

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

slesh ()
Ответ на: комментарий от slesh

> Как сделать так чтобы небыло такого?

Проверять результат, и продолжать запись с тех данных, что не были записаны.

С уважением, всегда ваш, К.О.

LamerOk ★★★★★ ()
Ответ на: комментарий от slesh

Теперь вопрос: Как сделать так чтобы небыло такого?

Перед записью проверяй с помощью epoll, что сокет готов для записи. Ну и смотри что возвращает write.

Deleted ()
Ответ на: комментарий от Deleted

В томто и дело что просто так не получится сделать потому как для посылки приходят с другова сервера. Были задумки такие: после получения события о том, что есть данные для чтения (пересылки клиенту), то проверять заполнение буфера и если нет свободного места, то просто не считывать данных. Но тогда придется отказаться от EPOLLET

slesh ()
Ответ на: комментарий от slesh

>В томто и дело что просто так не получится сделать потому как для посылки приходят с другова сервера.

Ну и что? Я не понял проблемы. %)

Есть у нас буфер на отправку. Если он не пустой, то ждем в epoll возможности записать в сокет. Дождавшись делаем write(). Ну и так далее, пока буфер не опустеет.

pathfinder ★★★★ ()
Ответ на: комментарий от slesh

>На стороне сервера шлю допустим 100кб и закрываю соедиенение.

А ты проверяешь возвращаемое значение от write/send? Оно точно в сумме дает ожидаемые 100kb или ты получаешь EAGAIN и игнорируешь его?

linuxfan ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.