Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2003.12.04;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.004 c
4-11713
qwerty2
2003-10-09 22:46
2003.12.04
Выполнить процесс от имени другого пользователя


9-11575
greenrul
2003-05-19 02:55
2003.12.04
Реализация изменцивых от ситуации диалогов в RPG:


4-11732
SkyN
2003-10-08 10:22
2003.12.04
Как вызвать событие onExit в DBLookupComboBox чужго приложения?


14-11703
electric
2003-11-12 20:12
2003.12.04
$$$ Money $$$


6-11692
Виноградов Алексей
2003-10-03 19:14
2003.12.04
Сервер на TServersocket и несколько клиентов.Многопоточность (+)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский