![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обработка событий от нескольких сокетов. [D7, XP]
Новичек © (2007-11-15 12:11:00)Здравствуйте, уважаемые Знатоки.
Имеется несколько потоков, в каждом из которых создается сокет.
Обработка событий от сокетов осуществляется с помощью вызоваWSAAsyncSelect(sctSocket, frmMain.Handle, WM_sctSocketEvent, FD_Read);
Обработчик выглядит следующим образом:
procedure TfrmMain.WMsctSocketEvent(var Msg: TMessage);
var
LenOfBuf: Cardinal;
Local: AnsiString;
begin
case WSAGetSelectEvent(Msg.lParam) of
FD_Read:
begin
ioctlsocket(WorkedSocket, FIONREAD, LenOfBuf);
SetLength(Local, LenOfBuf);
Recv(sctSocket, PChar(Local)^, LenOfBuf, 0);
if Pos(IniString1, Local) <> 0 then
begin
SendStr(sctSocket, Answer1 + #13#10);
Exit;
end;
if Pos(IniString2, Local) <> 0 then
begin
SendStr(sctSocket, Answer2 + #13#10);
Exit;
end;
end;// FD_Read
end;// case
end;
Процедура SendStr отсылает указанную строку на указанный сокет.
Теперь сам вопрос: если в этот обработчик будут поступать данные из множества сокетов, то на какой сокет будет отправлять данные процедура SendStr?
Спасибо.
Anatoly Podgoretsky (2007-11-15 15:45:00) [1]> Новичек (15.11.2007 14:47:19) [19]
Посмотри реализацию ICS он работает с десятками тысяч сокетов в одном потоке и у него нет проблем с определением сокета, работает как раз через WSocket
Сергей М. (2007-11-15 15:09:00) [2]
> как же все-таки реализовать обработку?
Использовать в кач-ве адресата окно того потока, который работает с интересующим гнездом.
Только вся эта асинхронная кухня здесь вряд ли нужна.
Ведь что такое "опрос терминала" ?
Как я понимаю, это отправка запроса + ожидание и получение ответа на этот запрос (возможно с последующей обработкой данных ответа). Если это так и если поток, создавший гнездо, кроме изложенного более ничем не занимается, нет никакого резона в транспорте с асинхронными нотификациями. Поток просто создает гнездо (создается оно всегда с опцией блок.режима ввода/вывода), после чего отправляет запрос и ждет ответ:
WSACheckResult(send(hSocket, sendbuf , ..);
WSACheckResult(recv(hSocket, recvbuf, ...);
ProcessResult(recvbuf, ..);
Новичек (2007-11-15 15:01:00) [3]Ухожу ненадолго, зайду позже.
Новичек (2007-11-15 14:47:00) [4]
> Ты указал одно и то же окно одного и того же потока в качестве
> адресата сообщений о событиях в нескольких гнездах.
Угу, верно, я и не спорю.
А как же все-таки реализовать обработку? Было бы неплохо из каждого потока посылать сообщение, но заранее неизвестно, сколько писать обработчиков :(
Вот и сижу, голова крУгом.
Сергей М. (2007-11-15 14:42:00) [5]
> Ведь не зря же в WSAAsyncSelect передается хэндл сокета
Конечно не зря.
Впоследствии он будет фигурировать в Msg.wParam.
>
> Именно сразу
Ну где же "сразу" ?
Ты указал одно и то же окно одного и того же потока в качестве адресата сообщений о событиях в нескольких гнездах.
Оконные сообщения поток-владелец окна-адресата будет выбирать/обрабатывать по одному последовательно, в порядке их следования в очереди сообщений.
Новичек (2007-11-15 14:35:00) [6]
> Так ты же не сразу их опрашиваешь, а последовательно)
Именно сразу - создал кучу потоков, в них делается все остальное.
Вот только никак не дойдет до меня, как проще сделать обработку поступающих данных. Ведь объявить обработчик событий от одного сокета можно лишь раз, а как в нем потом разделить сокеты? Смутное предчуствие, что как-то это можно реализовать, у меня есть. Ведь не зря же в WSAAsyncSelect передается хэндл сокета.
Сергей М. (2007-11-15 14:26:00) [7]
> опросить сразу все терминалы (чтоб быстрей было)
Так ты же не сразу их опрашиваешь, а последовательно)
Новичек (2007-11-15 14:24:00) [8]Блин, ADSL все время рвется...
> Ну так сделай по образу и подобию тех компонентов, которые
> "работают безукоризненно")..
С этим проблем нет.
Дело в другом. Я давно и успешно использую WSA. Трудность появилась при решении опросить сразу все терминалы (чтоб быстрей было) с использованием API.
Вдобавок, с WSA напрямую гораздо проще работать (по крайней мере, для меня).
Сергей М. (2007-11-15 14:16:00) [9]
> теперь хочется что-то и ручками сделать
Ну так сделай по образу и подобию тех компонентов, которые "работают безукоризненно").. Они же все с исх.текстами)... Что мешает изучить эти тексты на предмет как вся эта кухня правильно реализуется ?
Новичек (2007-11-15 14:07:00) [10]2Сергей М.:
Почему не угодили? Очень даже угодили. Я написал версию с Indy, версию с ICS, версию с Synapse - все версии работают безукоризненно.
А теперь хочется что-то и ручками сделать.
Сергей М. (2007-11-15 14:01:00) [11]
> Новичек
Чем готовыекомпоненты не угодили ?
Новичек (2007-11-15 13:31:00) [12]2Vice____:
Задача такая: следует опросить несколько терминалов (по телнету), количество которых заранее неизвестно. Потоки выбрал из-за того, что с их помощью можно организовать опрос сразу всех терминалов. Ежели есть другие идеи - приму с благодарностью.
Vice____ (2007-11-15 13:10:00) [13]
> Новичек (15.11.07 12:50) [9]
насмелюсь сказать:)
а может копнуть в сторону компонентов и избавится от потоков, хотя смотря какая там задача
Новичек (2007-11-15 12:50:00) [14]Понял. Спасибо, сударь, за указание, куда копать :)
Сергей М. (2007-11-15 12:47:00) [15]Следует или не следует - решать тебе.
Но решение, описанное тобой в [5], откровенно ошибочное.
Новичек (2007-11-15 12:46:00) [16]2Сергей М.:
Я так понимаю, следует организовать массив сокетов?
Сергей М. (2007-11-15 12:43:00) [17]
> Новичек (15.11.07 12:40) [5]
Ну и как, по-твоему, одна и та жепеременная будет хранить хендлы несколькихгнезд одновременно ?
Новичек (2007-11-15 12:40:00) [18]2Сергей М.:
Прошу прощения, не понял сразу.
Сокет объявлен глобально, инициализируется в каждом потоке.
Сергей М. (2007-11-15 12:35:00) [19]
> sctSocket типа TSocket
>
Я тебя не спрашиваю про тип)
Ежу понятно, что это хэндл гнезда.
Я спрашиваю - какого конкретно гнезда ? Т.е. где эта переменная объявлена, при каких условиях и как она иниц-ся значением хэндла этого гнезда ?
Новичек (2007-11-15 12:33:00) [20]2Vice____:
Нет возможности, т.к. сокеты на работе, а я там буду только после 20:00.
2Сергей М.:
sctSocket типа TSocket