| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Сети > TServerSocket/TClientSocket, не проходят сообщения |
| Автор: DelphiTester 14.5.2007, 20:37 | ||
У меня сервер рассылает по всем клиентам следующим кодом:
Проблема в том, что если подключились подряд 5 клиентов и первый "выпал" (отконнектился), то сообщения проходить не будут и до остальных. Это можно как-нибудь обойти, чтобы вылетев один клиент не вмешивался в работу остальных? |
| Автор: drkot 14.5.2007, 20:56 |
| клиент отключается как? disconnect или обрыв соединения? попробуй обработку исключений. |
| Автор: DelphiTester 15.5.2007, 01:03 |
| Клиент отключается именно обрывом соединения. А что в этой обработке исключений мне писать? Чего там надо обрабатывать? Не представляю как серверу указать, что клиент случайно вылетел.. |
| Автор: drkot 15.5.2007, 10:10 |
| После того как система закроет соединение по таймаут, передача данных продолжится. Думаю в данном случае нужно создавать поток для каждого клиента, и думать над методом синхронизации (если это нужно). Возможно стоит обратить внимание на протокол UDP. |
| Автор: DelphiTester 15.5.2007, 10:22 |
| На UDP не очень-то "хочется" обращать внимание. Клиентов относительно не много - 5-10. А использовать широковещательные запросы для такого кол-ва, не знаю, имеет ли смысл? А самостоятельно нельзя ли закрывать соединение с клиентом которые отсоеденился? |
| Автор: Snowy 15.5.2007, 12:29 |
| 1. крути цикл в обратную сторону - от кол-ва до 0. 2. Перед отправкой, проверь, активен сокет или нет. |
| Автор: drkot 15.5.2007, 13:31 |
насколько я знаю состояние активности не поможет. Snowy, а в чем фокус? а где я писал о широковещательных? просто TCP требует установления соединения, а UDP нет. В UDP обрыва соединения быть не может |
| Автор: Snowy 15.5.2007, 13:43 |
| Ну мало ли... Может и поможет Помести SendText в try .. except. По except прибивай коннект. Потому что пока ты крутишь цикл, кол-во соеденений может измениться в меньшую сторону. Тогда поймаешь глюку... Так уж устроены сокеты. Если клиент отвалился, не сообщив об этом, то сервер может не узнать об этом ещё некоторое время. Причём это время может достигать получаса. |
| Автор: drkot 15.5.2007, 14:01 |
Тогда глюка бы имела вид обращения к несуществующему объекту. А если клиент ушел по английски то при использовании TCP неизбежно напоришся на тиме оут Выход один (в моем понимании) на каждого клиента свой поток, если поток начинает тупить то мы его прибиваем. PS: и все таки UDP будет хорошей таблеткой от гимороя |
| Автор: Snowy 15.5.2007, 14:05 |
| Автор: Хрипа 15.5.2007, 17:40 |
| Я делал иначи.. Опрашиваю клиентов в сети или нет. И только отсылаю тем что в сети.. проверку Зделай |
| Автор: DelphiTester 15.5.2007, 17:47 |
| Snowy 2. А как проверить активен ли данный клиент? (соединение). Я не нашёл подобных методов у клиента.. Хрипа Данные передаются слишком часто, чтобы перед каждой передачей пытаться делать опрос. drkot Ты имел ввиду "ручную" рассылку циклом через UDP? Вообще UDP у меня ассоциируется с широковещательной рассылкой по сети. |
| Автор: Хрипа 15.5.2007, 21:36 |
| DelphiTester, 100% надо проверять Чел онлайн или нет.. Или использывать события онДисконект и базу данных любую хоть даже текстовую. При дисконекте удалять с базы не верного юзера и при конекте добовлять (при помаши Timer1). И только тем кто в базе отсылать данные. или хранить их всех и менять только режим Онлайн или нет... ну это тучь тяжелей без SQL |
| Автор: DelphiTester 15.5.2007, 23:13 |
| А как проверить онлайн он или нет?? Насколько я понял при таком "случайном вылете" клиента никаких ошибок не следует и обрабатывать нечего.. Как же узнать, что он отконнектился? Как опрос сделать? (надеюсь не послать ему строку и если он в ответ ответит..... Всё-таки такая технология совсем всю сеть загрузит и правда думать прийдётся о UDP протоколе.) |
| Автор: DelphiTester 16.5.2007, 17:02 | ||
Не понял.. а можно поподробнее о чём Вы хоть хотели сказать? Можно пример кода? |
| Автор: drkot 16.5.2007, 19:54 |
| Под "точно также" понимается, что работа с udp практически такаяже как и с tcp http://www.citforum.ru/internet/tifamily/udpspec.shtml |
| Автор: DelphiTester 17.5.2007, 01:34 |
| Но UDP использовать можно только в том случае, если не важно доходят данные или нет. А если важно? Приходится опять о TCP думать и опять-таки вопрос. А как проверить не отвалился ли текущий клиент? |
| Автор: DelphiTester 17.5.2007, 17:50 |
| Кто-нибудь что-либо сможет подсказать? например, как сделать проверку активности текущего клиента? (через TCP ессно) |
| Автор: Snowy 17.5.2007, 17:56 |
| У клиента же и спросить... |
| Автор: DelphiTester 17.5.2007, 18:52 |
| Дык как спросить-то? Вот здесь: "ServerSocket1.Socket.Connections[I].", я так и не смог найти как именно "спросить" клиента, активно ли именно с ним соединение в данный момент или нет.. |
| Автор: DelphiTester 17.5.2007, 19:47 | ||
Пробовал посылку модифицировать так:
результатов не дало. except ни в каком случае не срабатывает. (т.е. не при выключенных клиентах, ни при отключенных, всегда условие "успешности" выполняется... Как же в этом случае бороться с этой ерундой? |
| Автор: AugMaster 22.5.2007, 02:11 |
| выложи ПОЛНЫЙ код серверной проги, и будет тебе щастье. Потому как сейчаз хитрый случай походу, и мы тут на кофейной гуще гадаем. |
| Автор: drkot 22.5.2007, 09:41 |
| DelphiTester, Покупка билета еще не есть гарантия что попадеш на поезд (в театр и тд), но почемуто все покупают. Одного желания (даже если оно очень большое) мало для достижения цели. Нужно эще иметь хотябы отдаленное представление о том что именно ты хочеш сделать, а главное КАК? Ответы на вопрос КАК обычно есть в толстых умных книжках. Из твоих слов могу сделать вывод, что о сетевых протоколах ты практически ничего не знаеш, принципа работы не понимаеш, а работать пытаешся. Парадокс, однако |
| Автор: DelphiTester 22.5.2007, 09:55 |
| Согласен. Проблема разрешилась, косяк был на моей стороне, это никак не относится к сокетам. Добавлено через 2 минуты и 26 секунд Предлагаю переключиться на другую мою проблему http://forum.vingrad.ru/forum/topic-152421.html |
| Автор: Gwire 23.8.2007, 21:48 | ||||||||
| У TServerSocket есть такие события как: OnClientConnect; OnClientDisconnect; OnClientError. TCustomWinSocket имеет свойства SocketHandle: Integer. А также есть тип TList "хранящий" элементы типа Pointer. Замечу что SizeOf(Pointer) = SizeOf(Integer) Как это тебе поможет?..
Предположим, что клиент подключился...
Проходит время, клиент отключился...
А если клиента убило или разсоединило...
Как читать из ListClientTCP учить тебя не буду (просто Integer(ListClientTCP.Items[i]) ). Удачи. |
| Автор: AugMaster 26.8.2007, 01:13 | ||
у меня прога на серверном сокете, кол-во соединений в среднем от 200 до 900. И глюка действительно имеет вид "OutBound"-чего-то там. Но смысл ее ловить, когда можно избежать этого,просто крутя цикл в обратную сторону ? Насчет таймаут- когда роутер глюкавит, таймаут может достигать больших величин,и при этом при отправке клиенту данных никаких эрроров тебе не пишет, просто данные уходят в никуда. |