Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.12.04;
Скачать: CL | DM;

Вниз

closesocket   Найти похожие ветки 

 
Verg ©   (2003-10-09 13:37) [0]

все таки, когда можно делать closesocket? Я имею ввиду неблокирующий сокет.
Как гарантировать, что все данные были приняты (все FD_READ обработаны)?

Вот я обрабатываю FD_READ, вызываю ф-цию recv, но беру не все данные, а удобную мне порцию. Если это не все данные, то немедленно возникнет еще один FD_READ и т.д. И вот ситуация - противоположная сторона отсылает мне данные одним большим куском и тут же закрывает свой сокет. Так вот, если я произвожу чтение принятых данных описанным выше способом, то не могу ли я нарваться на FD_CLOSE среди тех событий FD_READ, и не приму ли, таким образм, всех данных до конца?

Какую роль в этой "кухне" играет SO_LINGER?


 
Digitman ©   (2003-10-09 13:59) [1]


> Какую роль в этой "кухне" играет SO_LINGER?


весьма важную играет
опция имеет смысл только для передающей стороны и дает возможность использовать механизм graceful shutdown

почитай внимательно топик станд.хэлпа sock2.hlp

"Graceful shutdown, linger options and socket closure"

там достаточно четко описано поведение обеих сторон вирт.петли для всех случаев


 
Verg ©   (2003-10-09 14:17) [2]

Я читал и вот как понял:
Если мы включим linger с ненулевым интервалом, то closesocket не закроет сокет до тех пор, пока все данные из буферов не будут посланы противоположнгой стороне. Так? Т.е. как бы надо включить. Ну а как же тогда понимать:

Enabling SO_LINGER with a nonzero time-out interval on a nonblocking socket is not recommended.

???

Чего они хотят сказать? Почему не рекомендуется? А что же тогда для неболкирующего сокета?


 
Digitman ©   (2003-10-09 15:16) [3]


> Почему не рекомендуется?


ну очевидно потому что closesocket() немедленно вернет управление вызвавшему коду с отказом WSAEWOULDBLOCK. Т.е. гнездо не будет закрыто сейчас же, а закроется только тогда когда истечет интервал тайм-аута, причем - "втихую", что не позволит тебе проконтролировать результат выполнения pending-операции по передаче текущего буфера (FD_WRITE как факт освобождения буфера попросту не возникнет, и ты никак не узнаешь, был ли буфер успешно "вытолкан в линию")


> А что же тогда для неболкирующего сокета?


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


 
Verg ©   (2003-10-09 15:34) [4]


> ну очевидно потому что closesocket() немедленно вернет управление
> вызвавшему коду с отказом WSAEWOULDBLOCK.


В деструкторе делаю так. Вроде катит.

while closesocket(FSocket)= SOCKET_ERROR do
begin
if WSAGETLastError<>WSAEWOULDBLOCK then break;
sleep(100);
end;



> то почему бы не подождать явно с его закрытием до тех пор
> пока не будет целеком и успешно передана последняя инф.структура
> ?


Что значит "явно подождать"? Кому подождать? Передающей стороне?

Передающая сторона делает

Sds:=send(s, buf, count);
if Sds = count then closesocket(s) else
..................

Чего и как ей "ждать"?


 
Digitman ©   (2003-10-09 16:02) [5]

а в этом случае ничего и ждать не нужно)

условие Sds = count же выполнилось ! значит смело можно закрывать гнездо : все что нужно было передать (все целиком count байт), успешно помещено в транспортный поток передачи

в ходе же закрытия гнезда следует воспользоваться опять же фигурирующей в хэлпе рекомендацией :

To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. For example, to initiate a graceful disconnect, an application could:

1. call WSAAsyncSelect to register for FD_CLOSE notification,
2. call shutdown with how=SD_SEND,
3. when FD_CLOSE received, call recv until zero returned, or SOCKET_ERROR, and
4. call closesocket,


 
Verg ©   (2003-10-09 16:20) [6]

Ну то есть реально-то linger можно и не трогать...


 
Digitman ©   (2003-10-09 16:21) [7]


> Verg


получается так
поэкспериментируй все же при плохих сетевых условиях



Страницы: 1 вся ветка

Текущий архив: 2003.12.04;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.011 c
1-11611
Walrus
2003-11-25 20:33
2003.12.04
Изменение объектов одного модуля из другого модуля


6-11641
Wiz@rd
2003-10-10 12:41
2003.12.04
Как указать настройки прокси сервера?


4-11748
_qq
2003-10-06 12:30
2003.12.04
Как открыть стандартное окно добавления шрифтов(


4-11737
maxi
2003-10-07 08:57
2003.12.04
Как узнать имя пользователя домена по его аккаунту ????


6-11695
Qwerr
2003-10-03 16:07
2003.12.04
Почта