Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обработка событий от нескольких сокетов. [D7, XP]


Страницы:   1 2

Новичек ©   (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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо