![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Асинхронные сокеты "забивают" очередь сообщений
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]Показывай код обработки оконных сообщений. посылаемых созданными тобой гнездами ...