Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.05.20;
Скачать: CL | DM;

Вниз

Использование TServerSocket/TClientSocket + TThread   Найти похожие ветки 

 
Konwin   (2006-11-14 17:44) [0]

Здравствуйте,

    Возникла необходимость написать приложение, соединяющееся по нескольким TCP портам и обрабатывающее (одновременно, т.е. распараллелено) поступающую по ним информацию. Было выбрано следующее решение:
Служба порождает нужное кол-во потоком (потомков TThread), каждый из которых соединяется с нужным портом (TClientSocket) и при получении информации обрабатывает её. Для проработки вопрос написал простенькие тестовые приложения: Сервер с потоком и компонентом TServerSocket и клиент с компонентом TClientSocket. После запуска приложения и потока порт слушается (проверял по netstat -na), после запуска другово приложения - происходит успешное соединение (тоже проверяно). Но! При попытке получить сообщение посланное 2-м приложением ничего не происходит, причём не происходит по причине того, что соответствующий обработчик просто не отрабатывает - на приложении с сервером но без потока точно такой же обработчик давал положительный рез-т.

Внимание вопрос - нет ли какой-то специфики процесса обработки сообщений, которую я не учёл?


 
DVM ©   (2006-11-14 18:18) [1]


> нет ли какой-то специфики процесса обработки сообщений

Каких сообщений? От кого кому сообщения?


 
SpellCaster   (2006-11-14 19:32) [2]

Если ты сделал на неблокирующих, то на фиг нужны потоки?


 
kami ©   (2006-11-14 22:26) [3]

Каким образом соединяются потоки с TXSocket?


 
Сергей М. ©   (2006-11-15 08:09) [4]


> Каким образом соединяются потоки с TXSocket?


Никаким.

Мухи это мухи, а котлеты это котлеты.

Приводи код...


 
Konwin   (2006-11-15 10:59) [5]

Не уверен что имеет смысл код приводить - на самом деле он на C++ Builder.
Там в целом всё очень просто - у каждого потока есть объект класса TDataModule, на котором я расположил компоненту TServerSocket (в тестовом приложении). Потоки нужны по простой причине - каждый поток должен обрабатывать данные своего порта независимо от остальных, и вообще говоря параллельно. Проюлема же заключается в следующем - у меня не отрабатывает событие OnClientRead, т.е. я не могу прочитать содержимое пришедшего пакета.
Причём тот же самый код в простом приложении без потоков нормально работает.


 
Сергей М. ©   (2006-11-15 11:05) [6]


> у меня не отрабатывает событие OnClientRead


Оно и не отработает, если ServerType = stNonBlocking и в потоке, активировавшем ServerSocket, нет цикла ожидания/выборки/диспетчеризации оконных сообщений.


 
Konwin   (2006-11-15 11:30) [7]


> Оно и не отработает, если ServerType = stNonBlocking и в
> потоке, активировавшем ServerSocket, нет цикла ожидания/выборки/диспетчеризации
> оконных сообщений.


А как в таком случае при использовании компоненты TThread использовать компоненты, работа которых основана на событиях? Если честно я никогда не пробовал организовывать цикл обработки вручную. Насколько я понимаю в этом случае сообщение будет приходить в основной поток приложения - как мне его перенаправить в поток?


 
SpellCaster   (2006-11-15 11:37) [8]

> [7] Konwin   (15.11.06 11:30)

Юзай блокирующие сокеты, на фига тебе события?
И кстати, смысл делать TDataModule, если можно напрямую создать TServerSocket ?


 
Сергей М. ©   (2006-11-15 11:38) [9]


> Насколько я понимаю в этом случае сообщение будет приходить
> в основной поток приложения


Неправильно понимаешь.
Оконные сообщения адресуются именно окнам, а не потокам.
За своевременное получение любых сообщений, адресованных некоему окну , ответственен именно тот поток, который создал это окно. В твоем случае это тот самый TThread, который активирует объект TXXXXXXSocket.


> А как в таком случае


Например, вот так:

while not Terminated and GetMessage(Msg,0,0,0) do
 DispatchMessage(Msg);


 
Konwin   (2006-11-15 11:46) [10]


> Оконные сообщения адресуются именно окнам, а не потокам.


Как же в таком случае работают приложения окон не имеющие - например службы - там ведь события прекрасно работают.....


 
Сергей М. ©   (2006-11-15 11:48) [11]


> Konwin


Боюсь, что твое решение использования в каждом доп.потоке отдельного экз-ра TXXXXXXSocket ничем не оправдано.

Собственно транспортом (прием/передача данных) для всех гнездовых соединений вполне может заниматься и один поток - транспортные операции как правило не времяёмкие. А вот обработку принятых/передаваемых данных вполне можно поручить доп.потокам, если эта обработка - времяёмкая операция.


 
Сергей М. ©   (2006-11-15 11:54) [12]


> приложения окон не имеющие - например службы


Если ты о TServiceApplication, то ошибаешься - осн.поток сервис-приложения при старте создает как минимум одно окно.


 
Konwin   (2006-11-15 11:54) [13]


> Боюсь, что твое решение использования в каждом доп.потоке
> отдельного экз-ра TXXXXXXSocket ничем не оправдано.
>
> Собственно транспортом (прием/передача данных) для всех
> гнездовых соединений вполне может заниматься и один поток
> - транспортные операции как правило не времяёмкие. А вот
> обработку принятых/передаваемых данных вполне можно поручить
> доп.потокам, если эта обработка - времяёмкая операция.
>


Оно не столько времяёмкое, сколько должно быть просто параллельным - потому что программа является сборщиком логов со станций в реальном времени, и станции посылают данные независимо друг от друга и как правило одновременно... Насколько я понял (раньше сетевых приложений к сожалению не писал - больше для БД) - на каждый прослушиваемый порт создаётся отдельный поток - можно ли каждому такому потоку как-то сопоставить отдельный обработчик? Т.е. иными словами - как будет осуществляться обработка пакетов пришедших одновременно на разные порты?


 
Сергей М. ©   (2006-11-15 12:18) [14]


> Оно не столько времяёмкое, сколько должно быть просто параллельным


Вовсе не обязательно. Это зависит, в первую очередь, от временных требований в протоколе инф.обмена со "станциями". Да и "реальное время" - термин не применимый для мультизадачной ОС.


 
Сергей М. ©   (2006-11-15 12:19) [15]


> как будет осуществляться обработка пакетов пришедших одновременно
> на разные порты?
>


У тебя что, куча компонентов TServerSocket создается ? А зачем ?


 
Konwin   (2006-11-15 12:42) [16]

Только что всё малость переделал - теперь в потоку запускается не сервер, а клиент - это ничего не изменилось - сообщения как не доходили, так и не доходят... Такое чувство что получает окно приложения и на этом всё кончается - ведь там обработать их некому.


 
Сергей М. ©   (2006-11-15 12:47) [17]


> теперь в потоку запускается не сервер, а клиент - это ничего
> не изменилось - сообщения как не доходили, так и не доходят


И не дойдут. По той же причине.


> получает окно приложения и на этом всё кончается - ведь
> там обработать их некому


"Там" это где ?


 
Сергей М. ©   (2006-11-15 12:55) [18]

TMyThread = class(TThread)
private
 procedure DoRead(Sender: TObject; Socket: TCustomWinSocket);
protected
 procedure Execute; override;
end;

procedure TMyThread.Execute;
var
 cs: TClientSocket;
begin
try
  cs := TClientSocket.Create(nil);
  try
    cs.Address := ...;
    cs.Port := ...;
    cs.OnRead := DoRead;
    cs.Open;
    while not Terminated do begin
      if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
        DispatchMessage(Msg);
      Sleep(0);
    end;
  finally
    cs.Free;
  end;
except
  MessageBox(0, "Грабли !", "", mb_ok or mb_setforeground);
end;
end;

procedure TMyThread.DoRead;
begin
 MessageBox(0, "Произошло событие OnRead", "", mb_ok or mb_setforeground);
end;



Страницы: 1 вся ветка

Текущий архив: 2007.05.20;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.041 c
2-1177662472
SerMaxx
2007-04-27 12:27
2007.05.20
как объявить функцию?


1-1174481739
kilya
2007-03-21 15:55
2007.05.20
MDI формы


2-1177540151
Kostafey
2007-04-26 02:29
2007.05.20
Подскажите как очистить GroupBox от визуальных компонентов ?


2-1177672097
Perf2k2
2007-04-27 15:08
2007.05.20
Строка из ListView передается не полностью


2-1177592173
sadasd
2007-04-26 16:56
2007.05.20
TClientSocket