Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Клиент-серверные приложения на сокетах


Автор: agx 20.2.2007, 15:06
Добрый день!
Плиз, подскажите, как быть: есть клиент-серверное приложение. К серверу одновременно может быть подключено множество клиентов, каждый из которым может периодически обмениваться данными в обе стороны. Как сервер может узнать, что соединение с клиентом потеряно? Тоесть, клиент не закрывал сокет со своей стороны, а просто, скажем, оборвался сетевой шнур. Данные от клиента, разумеется, не приходят, сервер пишет в сокет данные, которые до клиента тоже, само собой не доходят. И не возникает никаких exception-ов! Получается, что посланные данные теряются. Как сервер может определить, есть ли связь с клиентом? Единственое, что я смог придумать, это делать постоянный пинг и ставить таймаут на операцию считывания ответа от клиента. Но ИМХО это изврат, должно ведь в механизме TCP/IP сокетов это как-то автоматизировано?

Автор: LSD 20.2.2007, 15:17
Цитата(agx @  20.2.2007,  15:06 Найти цитируемый пост)
сервер пишет в сокет данные, которые до клиента тоже, само собой не доходят. И не возникает никаких exception-ов!

Почему не возникает? Очень даже возникает, при отправке данных ту получишь ошибку.

Автор: agx 20.2.2007, 15:39
Тоесть метод write() должен генерить IOException? Я тоже так думал, но экшепшена не возникает! Клиент отвалился, но сервер продолжает слать ему данные, как ни в чем не бывало! Может у меня уже глюки? %)

Автор: LSD 20.2.2007, 15:42
Попробуй после вызова write() вызвать flush().

Автор: COVD 20.2.2007, 16:55
Цитата

Единственое, что я смог придумать, это делать постоянный пинг и ставить таймаут на операцию считывания ответа от клиента. Но ИМХО это изврат, должно ведь в механизме TCP/IP сокетов это как-то автоматизировано? 


Это не "изврат", а нормальная практика. Исключение рано или поздно выскочит. Но период неопределенности может быть недопустимо большим для приложения. А пинг и таймаут вы контролируете сами.

Автор: agx 26.2.2007, 13:01
flush() вызывать пробовал, та же проблема.
Примерно секунд через сорок после обрыва связи исключение стабильно вылетает на методе read().
Был найден такой выход:
Писать сообщения в сокет и параллельно сохранять их в очереди. Обязать клиента на каждое собщение отсылать уведомление о получении. При приеме каждого уведомления удалять сообщение из начала очереди. При превышении очередью определенной длины запускать таймер, в течении которого, если клиент не пришлет недостающие отчеты (неотвеченных сообщений не станет меньше заданого числа), он будет отключен. Ну и точно также, при SocketException отключать клиента. А при повторном подключении досылать им все сообщения из очереди.
Как считаете, нормальный алгоритм, или можно придумать что-нибудь получше?

Автор: LSD 26.2.2007, 15:33
Цитата(agx @  26.2.2007,  13:01 Найти цитируемый пост)
Как считаете, нормальный алгоритм, или можно придумать что-нибудь получше?

По мне нормальный.

Автор: COVD 26.2.2007, 19:33
нормальный

Автор: Aizek 10.5.2008, 17:28
Придуманный велосипед ИМХО smile) Обратный ответ называется квитанция, правда когда мы ее мучали проверяли правильный ли приходит пакет или нет, если нет, повторная передача. А если ответа нет, тогда таймаутsmile А теперь хотелось бы спросить у знающих людей по той же теме, у меня есть клиент и сервер, просто содранный с примеров на виндграде http://forum.vingrad.ru/faq/topic-158005/hl/ssl++rmi/index.html . У меня возникает такой вопрос, насколько я понял данный клиент-сервер могут общаться только раз на раз и другой клиент к серверу подключиться не может. Что надо сделать, чтобы сервер мог общаться с несколькими клиентами? Придется делать потоки? На форуме нашел, что надо реализовать http://forum.vingrad.ru/forum/topic-199174.html  Вот в общем и все, что хочу узнать. Не хочу просто создавать еще одну тему.

Автор: Aizek 10.5.2008, 18:15
Нашел еще одну http://rox-xmlrpc.sourceforge.net/niotut/#NIO%20and%20SSL%20on%201.4 , она может решить мою проблему?
ЗЫ пока сижу вчитываюсь...

Автор: vodking 13.5.2008, 12:23
Правильный, радикальный, и, как показывает практика, единственный выход - юзать java.nio.channels. Исключение появляется мгновенно, даже на юниксах, где java.io вообще просто молчит при разрывах связи.

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