|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
25.07.2010, 13:48 | #1 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
TCPServer и TCPClient - как работать?
Здравствуйте, коллеги. Такой вопрос: как работать с этими компонентами в блокирующем многопоточном режиме? Инфы в инете перерыл море, кругом вода и полезного мизер.
Вот код, который я мучаю. Здесь есть клиент, отсылающий каждую секунду пакет данных. Если ответа от сервера не приходит, он пишет данные в черный ящик, и только когда пришел ответ от сервера о получении, то клиент сбрасывает все содержимое ящика. http://3dh.nm.ru/0.rar Люди, подскажите или киньте ссылки на их использование. Пожалуйста! Очень нужно!
"ковыряю изнутри" (с)
|
26.07.2010, 11:57 | #2 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
Люди, ну если неохота код шарить, хоть линками ткните мне про эти компоненты или книги, где про них есть хоть что-нить. Хочу построить клиент-сервер именно на них, ибо знаю, что вещь мощная и можно с лихвой обойтись без винсока
"ковыряю изнутри" (с)
|
27.07.2010, 09:58 | #3 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
ладно, тогда конкретные вопросы. Говорю сразу: TCPClient в режиме bmBlocking, TCPServer - bmBlockThreading.
1) как корректно завершить сервер, разорвав все потоки соединения? Просто TCPServer.Close в событии вормы onDestroy? 2) у клиента в тайсере идет передача и прием данных. Сначала клиент получает данные от сервера. И если получена строка-сигнал, то клиент отправляет дальше в этом же таймере, т.е. здесь вызовы ReciveLn и SendLn код: Код:
"ковыряю изнутри" (с)
|
27.07.2010, 10:09 | #4 |
Заблокирован
Регистрация: 27.05.2010
Сообщений: 1,099
|
> Просто TCPServer.Close в событии вормы onDestroy?
TCPServer.Free; Но следует принять алгоритмические меры к тому чтобы треды клиентских соединений максимально оперативно реагировали на флаг Terminated. |
27.07.2010, 10:39 | #5 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
хорошо, более подробно.
Такой код будет корректен? Код:
"ковыряю изнутри" (с)
Последний раз редактировалось 3D Hunter; 27.07.2010 в 10:44. Причина: дополнение |
27.07.2010, 14:01 | #6 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
Не, ну так не пойдет. Народ, не спим. Первый вопрос остается в силе.
Теперь о втором вопросе. Код, представленный во 2м посте, заставляет приложение сдохнуть. Оно подвисает и ниуя не делает. Есть предположение, что после приема ReceiveLn клиент не может отослать данные. Может использовать свойство Receiving? Т.е. проверять вайлом, пока клиент в режиме приема, то нельзя отсылать пакеты. Или я не прав и на блокирующие сокеты это свойство не пашет? Исходники в первом посте. Ссылка прямая. Жду подсказок и советов. Пожалуйста Кстати, Свойство TCPServer.Close заставляет умереть переменную касса TServerSocketThread. Но не факт, что при уничтожении этого потока уничтожатся все его нити-сокеты. По крайней мере, в коде vcl такого не нашел
"ковыряю изнутри" (с)
Последний раз редактировалось 3D Hunter; 27.07.2010 в 14:04. Причина: дополнение |
27.07.2010, 14:11 | #7 |
Заблокирован
Регистрация: 27.05.2010
Сообщений: 1,099
|
procedure TFParser.tcp_parserAccept(Sender: TObject;
ClientSocket: TCustomIpClient); begin .. Application.ProcessMessages; Это что за ересь ? Какого черта ты в доп.треде обращаешься к потоконебезопасному объекту Application ? > Свойство TCPServer.Close заставляет умереть переменную касса TServerSocketThread. Не "умереть", а "разрушить объеат классаTServerSocketThread, ссылка на который хранится в приватном поле объекта". > не факт, что при уничтожении этого потока уничтожатся все его нити-сокеты Не факт. Особенно если поточные процедуры нитей реализованы криво. Последний раз редактировалось Stilet; 27.07.2010 в 16:55. |
27.07.2010, 16:40 | #8 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
к примеру, каждый сокетный поток должен записывать всю приходящую информацию в текстовый файл. Проблема возникает при выходе из программы. Метод TCPServer.ClearThreadPool сигнализирует всем потокам, что пора завершаться, и каждый поток не дописывает пришедший последний пакет до конца в файл, а только часть! Но ведь свойство Terminated проверяется в цикле, а этот метод устанавливает его в тру. А в цикле как раз и происходит запись в файл. Вроде должно все записываться.
mss, если вы знаете решение этой проблемы, укажите пожалуйста в приведенном коде на мои ошибки. А так только критикуете. Про Application.ProcessMessages учту.
"ковыряю изнутри" (с)
|
27.07.2010, 17:06 | #9 |
Заблокирован
Регистрация: 27.05.2010
Сообщений: 1,099
|
> свойство Terminated проверяется в цикле
Оно у тебя проверяется до/после блокирующего вызова ReceiveLn(), так что ничто не мешает после обнаружения Terminated = True прервать цикл с опросом флага Terminated и ДО выхода из поточной процедуры "дочитать" остаток доступной для чтения инф-ции циклическим вызовом ReceiveLn(), пока он не вернет пустую строку. Хотя здесь ждет засада - партнер по инф.обмену на другом конце соединения может уйти "покурить" на неопред.время, не разорвав соединение и не послав терминатор строки, что приведет к блокировке принимающего сокетного потока сервера на очер.вызове ReceiveLn на неопред.время. Что, в свою очередь, сделает невозможным корректное завершение работы TCPServer в ожидаемое время. |
27.07.2010, 17:16 | #10 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
патртнер по соединению - прибор, посылающий пакет раз в секунду и ждущий ответа сервера определенной строки 'ACCEPT r/n/'. Если прибор не получает подтверждения более 2 мин, то разрывает связь, после чего через 5мин стучится заново. При этом за время оффлайна он копит все данные приходящие раз в секунду. Т.е. при следующем соединении он перешлет инфу 1м пакетом за 7 мин.
"ковыряю изнутри" (с)
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
[Delphi] TCPserver, TCPclient | MASSIOMO | Работа с сетью в Delphi | 14 | 29.07.2010 17:53 |
TCPServer, TCPClient | seobot | Общие вопросы Delphi | 2 | 03.05.2010 23:56 |
TCPClient, TCPServer : SendBufer() | Zeraim | Работа с сетью в Delphi | 4 | 27.12.2009 21:22 |
TcpClient и TcpServer | DOLBY | Работа с сетью в Delphi | 5 | 17.12.2007 10:43 |
TCPServer и TCPClient | Antoha | Работа с сетью в Delphi | 19 | 06.10.2007 12:01 |