Главная страница
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.008 c
8-11629
Misha
2003-08-03 17:50
2003.12.04
форматы


3-11589
petr
2003-11-16 18:20
2003.12.04
исправление значения по умолчанию поля базы данных


6-11650
Alexx_AI
2003-10-10 16:34
2003.12.04
Программно в сеть W2000 XP


3-11590
chook
2003-11-03 06:23
2003.12.04
DBGrid


8-11618
Fenik
2003-07-23 01:39
2003.12.04
Метод Dormant