Форум: "Сети";
Текущий архив: 2007.05.20;
Скачать: [xml.tar.bz2];
ВнизИспользование 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.041 c