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

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

Асинхронные сокеты "забивают" очередь сообщений


Страницы:   1 2 3

SpellCaster ©   (2008-04-01 17:01:00) 

Делаю класс асинхронного сокета и столкнулся с проблемкой зависания проги. Прога коннектится к серверу и начинает принимать от него непрерывный поток данных. Соответственно, после каждого Recv в очередь сразу же ставится следующее сообщение с событием FD_READ, которое тут же и обрабатывается. В итоге сообщения от главного окна просто не могут пробиться сквозь этот цикл. Вместе с тем, если запускать в начале процедуры SocketEvent Application.ProcessMessages, то все работает (естественно). Однако есть у меня сомнение: ведь эта процедура сразу вытаскивает из очереди очередное сообщение. Вполне вероятно, что это может оказаться следующая мессага от того же сокета - и тогда SocketEvent будет запущен второй раз, а уже после обработки этого сообщения управление вернется к первой копии SocketEvent. То есть, к примеру, может получиться так, что сначала обработается FD_CLOSE, а потом придет очередь FD_READ, что не очень-то здорово.
Поэтому хочу спросить у знатоков, есть ли какой-то хороший путь решения данной проблемы? Или, может, я зря волнуюсь насчет перепутывания сообщений? В идеале хотелось бы иметь способ вместо ProcessMessages обработать только мессаги формы, а потом уже с чистой совестью заниматься с сокетом.
Посмотрел сорсы ICS, там реализована собственная выборка собщений. В принципе, можно сделать так же, но я пока не разобрался, как ее применять.
В общем, если что посоветуете, буду рад... только два условия:
1) Не хочется юзать нити
2) Видеть реплики типа "Зачем тебе это надо" и "не занимайся ерундой" также не горю желанием.


SpellCaster   (2008-04-02 11:48:00) [41]

> А если не установлено, то что творится в этой ф-ции ?

Устанавливается коннект с проксей. Приводить, наверно, не буду, но смысл в том, что в зависимости от состояния коннекта читаются или отправляются пакеты для установки связи.

> Это, разумеется, следует убрать.
Так тогда мессаги от юзера вообще не проходят!


Сергей М.   (2008-04-02 08:31:00) [42]


> HandleSocksConnect возвращает False, если соединение с соксом
> уже установдено


А если не установлено, то что творится в этой ф-ции ?


> Application.ProcessMessages;


Это, разумеется, следует убрать.


SpellCaster   (2008-04-01 17:33:00) [43]


// Socket message receiver
procedure TAsyncClientSocket.DoEvent(WParam, LParam: Longint);
var SockErr: Integer;
   Event: Word;
begin
 Event:=WSAGetSelectEvent(LParam);
 SockErr:=WSAGetSelectError(LParam);
 // если произошла ошибка
 if SockErr<>0 then
   begin DoError(WParam,Event,SockErr); Exit; end;

 // если пришло ожидаемое событие, обнуляем таймер
 if fRespEvent=Event then fRequestTime:=0;

 // на обработку соединялки с проксей отправляем только события READ и WRITE
 case Event of
   FD_CONNECT        : begin
                         fActive:=True;
                         if fProxyUsed then begin fSocksState:=ssConnecting; Exit; end;
                       end;
   FD_READ, FD_WRITE : if HandleSocksConnect then Exit;
   FD_CLOSE          : begin
                         fSocksState:=ssNone;
                         fRequestTime:=0;
                         Close;
                       end;
   else Exit;
 end;
 if Assigned(OnEvent) then OnEvent(Self,WParam,Event);
end;


ну и в программе


procedure TClient.SocketEvent(Sender: TObject; Sckt: TSocket; Event: Word);
var received: Integer;
   req: ShortString;
   Msg: TMsg;
begin
 Application.ProcessMessages;

 case Event of
   // сокет соединился
   MsgConnect:
     begin
        ...
     end;
   // в буфер сокета поступили данные
   MsgRead:
     begin
          ...
           begin
             // Проверяем результат: если ошибка - соединение закрываем и переподключаемся
             received:=fSock_in.Recv(@fBuf[0],PacketSize);
             if received<=0 then
               begin SetState(nsErr,'receive: '+WSALastErr); Close; Exit; end
             // всё ОК - пишем полученные данные в выходной поток и обнуляем счетчик попыток
             else
             begin
               ...
             end;
     end; // MsgRead
   MsgWrite  :   ;
   MsgClose  : begin
                 SetState(nsStop);
                 SetState(nsInactive);
               end;
 end;
end;



HandleSocksConnect возвращает False, если соединение с соксом уже установдено.


Сергей М.   (2008-04-01 17:09:00) [44]

Показывай код обработки оконных сообщений. посылаемых созданными тобой гнездами ...


Страницы:   1 2 3

Наверх

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