Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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.044 c
15-1176885549
DVM
2007-04-18 12:39
2007.05.20
Как будет по английски Ведущий разработчик? Как говорят?


3-1172760328
Alex2006
2007-03-01 17:45
2007.05.20
Проблема с Dialect?


2-1178093914
Perf2k2
2007-05-02 12:18
2007.05.20
ListView: как проверить, выеделена ли пустая строка или нет?


3-1172862873
ПоШЛяК
2007-03-02 22:14
2007.05.20
Копирование записей


1-1174928619
Alex___
2007-03-26 21:03
2007.05.20
Запуск процесса из службы в висте...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский