|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
20.12.2012, 16:03 | #1 |
Регистрация: 20.12.2012
Сообщений: 7
|
Серверное приложение с TCPServer. Правильно закрыть соединение.
Здравствуйте, товарищи!
Пишу серверное многопользовательское приложение, Delphi 7. За основу взял пример отсюда http://softengines.ru/showthread.php?t=6863 На всякий случай продублирую код Код:
Суть-вопросы. 1. Для закрытия соединения при получении команды 'BYE' используется вызов Terminate, который (как я понимаю) убивает клиентский поток. Правильно ли это? Не надо ли вызывать методы Disconnect, Close класса ClientSocket ? Проясните этот момент, кто знает. 2. Для меня сейчас более актуально разобраться в следующем: если клиент не отправляет команду 'BYE', а просто вырубается, рвется соединение и т.п., то цикл while в TcpServer1Accept начинает бесконечно гонять по кругу. Каждый раз ClientSocket.Receiveln возвращает пустую строку. Т.е. получается, что сокет висит в каком-то неопределенном состоянии (пробовал определять эту ситуацию проверкой ClientSocket.Connected, но ничего не вышло, остается TRUE), пользовательский поток гоняет по кругу цикл, который уже ничего не сделает, хотя должен умереть. Как правильно отследить и обработать эту ситуацию? В общем, научите правильно закрывать соединения со стороны сервера во всех случаях. Заранее спасибо. Последний раз редактировалось ispovedn1k; 20.12.2012 в 16:07. |
20.12.2012, 16:54 | #2 | |
Форумчанин
Регистрация: 11.04.2012
Сообщений: 212
|
Цитата:
Вызов Terminate всего лишь взводит флаг Terminated. И цикл Код:
Разрыв соединения о инициативе удаленного партнера, уходящего по-английски не попрощавшись, детектируется в обработчиках OnDisconnect и OnError. Вызов ClientSocket.Disconnect при обнаружении таких событий обязателен, иначе ClientSocket останется в статусе Connected. |
|
21.12.2012, 19:03 | #3 |
Регистрация: 20.12.2012
Сообщений: 7
|
Пока не смог разобраться, как правильно писать код перекрытой процедуры Execute.
Мое вмешательство в нее приводит к тому, что потоки начинают плодиться как кролики. А если внутри Execute я еще и цикл объявлю, то они становятся бессмертными кроликами! Однако, читая документацию, я нашел в описании метода SyncProc класса TClientSocketThread пример. Приведу его тут для наглядности Код:
Однако, если кто-либо покажет, как правильно перегружать Execute, буду признателен. Пойду разбираться с событиями onDisconnect и onError. З.Ы. пишу тут это все для того, чтобы потом кто-то смог быстро найти ответ и не шагал по моим граблям. Поэтому за помощь и правильные советы буду очень признателен я и не только... |
21.12.2012, 19:48 | #4 |
Форумчанин
Регистрация: 11.04.2012
Сообщений: 212
|
Если ты не планируешь выходить за рамки D7 и/или не боишься трудностей с адаптацией D7-кода к последующим версиям среды, то откажись пока не поздно от TTCPServer в пользу TServerSocket
|
21.12.2012, 20:20 | #5 |
Регистрация: 20.12.2012
Сообщений: 7
|
Наверное стоящая мысль. Я только разбираюсь с инструментами. С Делфи последний раз имел дело лет 10 назад еще в школе. Сейчас надо написать серверное приложение, способное обрабатывать много клиентских подключений, выполняющую при этом роль шлюза к БД.
С элементами такого проекта я раньше баловался на языке С. Обдумываю вариант, чтобы сделать просто консольное приложение на чистом Api без лишних библиотек и сторонних компонентов. Кажется мне, что этим можно (при грамотном подходе) повысить производительность. Можно даже сделать, при должном старании, версии и под Linux и под Windows. С другой стороны, есть готовые компоненты, с реализованной многопоточностью. Клиентское приложение, которое мне еще предстоит дорабатывать, тоже написано на D7. Но вот беда, по сути среду приходится изучать заново. Какой подход посоветуете? З.Ы. сейчас будет пост про OnErrpr, OnDisconnect, OnDestroyHandle |
21.12.2012, 20:33 | #6 |
Регистрация: 20.12.2012
Сообщений: 7
|
Итак, я поиграл немного с событиями и обработчиками. Как это было:
Код:
Код:
Код:
При нормальном отключении (т.е. клиет посылает строчку BYE) происходит OnDisconnect, OnDestroyHandle). Если клиент уходит "по-английски", то не происходит ничего! Клиентский поток зависает в бесконечном цикле, подминает под себя ресурсы процессора и... все! Единственно что, OnError срабатывает при закрытии серверного приложения, если было некорректное отключение. на долю секунды можно увидеть мелькнувшее сообщение об ошибке. Последний раз редактировалось ispovedn1k; 21.12.2012 в 20:38. |
21.12.2012, 20:38 | #7 | |
Форумчанин
Регистрация: 11.04.2012
Сообщений: 212
|
Цитата:
В случае с TServerSocket в режиме stThreadBlocking о событийном механизме обработки клиентского соединения можно вообще забыть. |
|
21.12.2012, 20:42 | #8 |
Регистрация: 20.12.2012
Сообщений: 7
|
Ну вот, а я так старался. Ладно. Пойду смотреть, что предлагает TServerSocket
|
21.12.2012, 21:02 | #9 |
Участник клуба
Регистрация: 07.12.2011
Сообщений: 1,025
|
TServerSocket не предлагает Receiveln - это небольшой недостаток
Не стесняемся, плюсуем!
|
21.12.2012, 21:04 | #10 |
Регистрация: 20.12.2012
Сообщений: 7
|
Хочу спросить, пока еще можно.
После обрыва соединения в потоке бесконечно гоняется цикл. Receiveln всегда возвращает пустую строку. А что если, скажем, после 5 подряд пустых строк вызывать Terminate? Попробовал, в этом случае закрывается соединение на сервере. Вроде бы разумно. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Клиент-Серверное приложение...? | spamer | Общие вопросы по программированию, компьютерный форум | 2 | 15.03.2012 12:42 |
Клиент Серверное приложение | BARNEY | Общие вопросы Delphi | 2 | 28.10.2010 09:30 |
Серверное приложение | Pliks | Общие вопросы по Java, Java SE, Kotlin | 2 | 20.11.2009 18:52 |
серверное приложение | blackbanny | Фриланс | 5 | 13.10.2009 02:11 |
Клиет - серверное приложение | Mitron | Работа с сетью в Delphi | 6 | 20.08.2007 19:57 |