Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Вопрос по winsock


Автор: Sergio 3.2.2007, 23:15
Здраствуйте. Сделал серверную и клиентскую часть по протоколу TCP. Использовал winsock.h И вот постала передо мной проблема. Как узнать что сервак отключился? Можно ли эту проблему решить без создания клиента на сервере? Может winsock2.h решает эти проблемы?

Автор: Dimonius 4.2.2007, 02:06
Используй функцию select() для работы с дескрипторами.
И, если recv() возвращает 0 (FIN), при этом не принимая никаких данных, значит сервер отключился.
В принципе, так у меня работало для Berkeley Sockets, но думаю, что и для winsock должно сработать.

Автор: witex 4.2.2007, 02:57
впринципе так и есть! потому что надо потоянный цикл  recv делать! вот и прикол в том что делаешь его пока он не равен 0 просто! если сервакотключился ! он из цикла выходит! вот и ставь любое действие после выхода из цикла! это действие будет значить что ты отключился от сервака! в любых исходникак протокола они есть!

Автор: ptr 4.2.2007, 08:50
Цитата(Sergio @  4.2.2007,  02:15 Найти цитируемый пост)
Как узнать что сервак отключился?

Отключился или потеряна связь?

Цитата(Dimonius @  4.2.2007,  05:06 Найти цитируемый пост)
Используй функцию select() для работы с дескрипторами.

А select зачем?

Цитата(Dimonius @  4.2.2007,  05:06 Найти цитируемый пост)
И, если recv() возвращает 0 (FIN), при этом не принимая никаких данных, значит сервер отключился.

Ну и про send надо не забывать.

Автор: vitaly1979 4.2.2007, 10:14
ptr, правильно заметил

при корректном закрытии удаленного конца  на своем сокете получаешь событие FD_CLOSE(WSAEnumNetworkEvents)
но это неблокирующие сокеты

если блокирующие, и если хочешь неглючную прогу, обязательно select!
recv блокирует прогу


Автор: Sergio 4.2.2007, 14:47
Я возможно неправильно выразился. Я хочу чтобы, когда из сервером потеряна чвязь клиент знал об этом и не продолжал посылать смс. Можно это сделать без клиентской части на серваку? 

Автор: witex 5.2.2007, 00:23
тебе же говорят! у тебя тожлен хоть какой то цикл стояь на recv.
Код

while( (bytes_recv=recv(my_sock,&buff[0],sizeof(buff),0)) &&
(bytes_recv !=SOCKET_ERROR))

Автор: ptr 6.2.2007, 06:29
Sergio, подожди, давай по-порядку. Я так понял, что ты продолжаешь писать чат.

Цитата(Sergio @  4.2.2007,  17:47 Найти цитируемый пост)
Можно это сделать без клиентской части на серваку? 

Что ты подразумеваешь под этим?

Цитата(Sergio @  4.2.2007,  17:47 Найти цитируемый пост)
Я хочу чтобы, когда из сервером потеряна чвязь клиент знал об этом и не продолжал посылать смс.

Если всё правильно сделано, то в этом случае send вернёт какую-нибудь из ошибок (правда возможно не сразу). Так что надо правильно написать обработку и всё будет нормально.

Есть правда другая проблема - контроль связи. TCP не выполняет опрос соединения.
Для большинства программ не нужно немедленно знать о потери связи, для других же это может иметь значение. Для контроля соединения можно использовать таймер keep-alive (правда чаще всего он бесполезен). Но обычно функциональность keep-alive реализуют на прикладном уровне, либо используют тайм-аут.

По этому вопросу рекомендую почитать Снейдера со Стивенсом.

Автор: vitaly1979 15.2.2007, 18:49
ptr, например для сокета с опцией keep-alive какое событие вы будете ловить?

Автор: azesmcar 16.2.2007, 17:01
Цитата

Используй функцию select() для работы с дескрипторами.
И, если recv() возвращает 0 (FIN), при этом не принимая никаких данных, значит сервер отключился.
В принципе, так у меня работало для Berkeley Sockets, но думаю, что и для winsock должно сработать.


Не все так просто (как хотелось бы) smile

0 возвращяется при нормальном завершении клиентского процесса. Если скажем процесс клиента убили то recv вернет SOCKET_ERROR а прочитав errno (под юникс) или просто GetLastError() (под виндоуз) станет ясно что его убили.
ошибка номер 10053 - клиента убили smile
и еще recv вам никогда не скажет что клиент погиб смертью храбрых в бою с электриком если вдруг последний решит вырубить свет..конкретнее если компьютер просто вырубится. На эти случае нужен  Keep-Alive.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)