The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"send не успевает отправить данные до close."
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Сеть, сокеты)
Изначальное сообщение [ Отслеживать ]

"send не успевает отправить данные до close."  +/
Сообщение от Wazar (??) on 31-Мрт-10, 12:24 
При написании HTTP сервера столкнулся с такой проблемой.

возвращаю ответ клиенту с помощью send одним куском килобайт в 10. сразу после этого делаю close.
Клиенту доходит не вся информация. Когда использовал сниффер со стороны клиента - видел что доходин только первый пакет в 1460 байт. При этом send возвращает всю длину переданного массива то есть вроде как передал все. Если после send не делать close (делать его минут через 5) до данные гарантировано доходят, но некоторые клиенты, например Internet Explorer, ждут именно окончания соединения, и Content-Length им не указ.
Компромисный вариант - делал sleep на 1 секунду. Вроде все успевает доходить и даже чуть чуть ждет. При чем как при отправке страницы так и при отправке файла мб в 10 время ожидания примерно одиноково.

Пробовал включать/отключать блокирующий режим, пробовал использовать shutdown. не помогает.

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "send не успевает отправить данные до close."  +/
Сообщение от anonymous (??) on 31-Мрт-10, 12:34 
Попробуйте говорить fsync() на дескриптор сокета.
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "send не успевает отправить данные до close."  +/
Сообщение от svn (??) on 31-Мрт-10, 16:29 
>Попробуйте говорить fsync() на дескриптор сокета.

Глупость. Сокет это не файл, сокеты не кешируются, и запись в них не откладывается.

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

2. "send не успевает отправить данные до close."  +/
Сообщение от svn (??) on 31-Мрт-10, 16:11 
Очевидно TCP стек работает не корректно. Возможно его ломает файрвол или неправильные настройки.

>пробовал использовать shutdown. не помогает.

Как именно пробовал? Закрывать надо на отправку.

Вообще закрытие сокета намного сложнее, и далеко не всегда требуется, в виду наличия в http протоколе keep-alive. Как, кто и в каком случае закрывает соединение - написано в последнем RFC по http.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

4. "send не успевает отправить данные до close."  +/
Сообщение от Wazar (??) on 31-Мрт-10, 17:38 
>>пробовал использовать shutdown. не помогает.
>
>Как именно пробовал? Закрывать надо на отправку.
>
>Вообще закрытие сокета намного сложнее, и далеко не всегда требуется, в виду
>наличия в http протоколе keep-alive. Как, кто и в каком случае
>закрывает соединение - написано в последнем RFC по http.

shutdown делал и SHUT_WR и SHUT_RDWR. Не помогло. И fsync - тоже.

На счет keep-alive - я шлю Connection: close

>Очевидно TCP стек работает не корректно. Возможно его ломает файрвол или неправильные
>настройки.

Не подскажите как и что надо настроить? Кст, сервер я тестировал под 10082 портом, а на 80 порту у меня висит апач. Так вот апач все нормально шлет и даже IE все устраивает.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

5. "send не успевает отправить данные до close."  +/
Сообщение от BigHo on 03-Апр-10, 17:47 
Что за операционная система и стоит ли опция LINGER на сокете? Скорей всего это баг ОС или её настроек (посмотрите в sysctl - по поводу msl).
Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "send не успевает отправить данные до close."  +/
Сообщение от guest email(??) on 04-Апр-10, 09:27 
>Что за операционная система и стоит ли опция LINGER на сокете? Скорей
>всего это баг ОС или её настроек (посмотрите в sysctl -
>по поводу msl).

Вопрос почти в тему)
Как ведет себя не блокируемый сокет с SO_LINGER?

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

7. "send не успевает отправить данные до close."  +/
Сообщение от BigHo on 04-Апр-10, 09:57 
>>Что за операционная система и стоит ли опция LINGER на сокете? Скорей
>>всего это баг ОС или её настроек (посмотрите в sysctl -
>>по поводу msl).
>
>Вопрос почти в тему)
>Как ведет себя не блокируемый сокет с SO_LINGER?

Из мана на setsockopt:

     SO_LINGER controls the action taken when unsent messages are queued on
     socket and a close(2) is performed.  If the socket promises reliable
     delivery of data and SO_LINGER is set, the system will block the process
     on the close(2) attempt until it is able to transmit the data or until it
     decides it is unable to deliver the information (a timeout period, termed
     the linger interval, is specified in seconds in the setsockopt() system
     call when SO_LINGER is requested).  If SO_LINGER is disabled and a
     close(2) is issued, the system will process the close in a manner that
     allows the process to continue as quickly as possible.

Если вкраце - то он как раз задерживает выполнение close до тех пор, пока все данные не будут отправлены. Вот только я его не разу не использовал, и все нормально работа(ет,ло). Только в одном случае я его бы использовал - при неблокирующем вводе/выводе. Потому как send в этом случае действительно возвращает размер буфера передаваемого буфера авансом, и последующий close будет ассинхронно разрывать поток, что видимо и наблюдается в вашем случае. Вот только если дескриптор работает в блокирующем режиме, то тогда я "ой".

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "send не успевает отправить данные до close."  +/
Сообщение от pavlinux email(ok) on 30-Авг-10, 03:03 
>При написании HTTP сервера

Зачем?

> столкнулся с такой проблемой.
> возвращаю ответ клиенту с помощью send одним куском килобайт в 10.

Наивный чукоцкий программер. Вероятность того, что все 10 кило дойдут
каким-то одним куском равна 0, хотя бы из того, что даже Jumbo frame равен 9000 байтам.


Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

9. "send не успевает отправить данные до close."  +/
Сообщение от Volodai on 19-Авг-11, 14:47 
> Наивный чукоцкий программер. Вероятность того, что все 10 кило дойдут
> каким-то одним куском равна 0, хотя бы из того, что даже Jumbo
> frame равен 9000 байтам.

Я бы сказал по другому, хотя бы потому, что всё что отправляется и имеет размер больше MTU будет некорректно отсылаться, если использовать Socket.
Размер MTU зависит от типа сетей. Для Ethernet он равен 1500 байт +/-, для Internet и того меньше, не помню точно, можно погуглить.
Так вот, большие пакеты нужно разбивать на куски размером меньше либо равно MTU.


Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

10. "send не успевает отправить данные до close."  +/
Сообщение от pavlinux (ok) on 19-Авг-11, 18:05 
>> Наивный чукоцкий программер. Вероятность того, что все 10 кило дойдут
>> каким-то одним куском равна 0, хотя бы из того, что даже Jumbo
>> frame равен 9000 байтам.
>  Я бы сказал по другому, хотя бы потому, что всё что
> отправляется и имеет размер больше MTU будет некорректно отсылаться, если использовать
> Socket.
> Размер MTU зависит от типа сетей. Для Ethernet он равен 1500 байт
> +/-, для Internet и того меньше, не помню точно, можно погуглить.

Это не наши проблемы. Нам интересен только MTU до первого маршрутизатора провайдера.

> Так вот, большие пакеты нужно разбивать на куски размером меньше либо равно
> MTU.

Этим занимается ядро. Не нужно лезть ниже 7 уровня OSI при написании HTTP сервера.

Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2020 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру