Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.25;
Скачать: CL | DM;

Вниз

WinSock.Select   Найти похожие ветки 

 
FireMan_Alexey ©   (2004-02-12 09:34) [0]

Ув. мастера прошу не подскажите пожалуйста где можно прочитать
как функция Select возращает значения о нескольких сокетах?
И можно ли использовать функцию Select вот так
Var
 SS:TFDSet;
 TV:TTimeVal;

Begin
...
Select(Socket_Count,@SS,@SS,@SS,@TV);
...

End;

или каждый раз нужно проверять отдельно

Begin
...
Select(Socket_Count,nil,@SS,nil,@TV);
Select(Socket_Count,@SS,nil,nil,@TV);
Select(Socket_Count,nil,nil,@SS,@TV);
...

End;


 
Verg ©   (2004-02-12 10:52) [1]


> или каждый раз нужно проверять отдельно
>
> Begin
> ...
> Select(Socket_Count,nil,@SS,nil,@TV);
> Select(Socket_Count,@SS,nil,nil,@TV);
> Select(Socket_Count,nil,nil,@SS,@TV);
> ...
> End;


Нет, не обязательно, можешь все вместе ждать.
Ф-ция вернет общее число сокетов, в которых произошли те события, которые ты заказал.

Далее, применяя FD_ISSET на каждом множестве TFDSET для тех сокетов, которых ты туда раньше навставлял с помощью FD_SET, ты определишь какой(кие) сокеты именно имеют "что сказать".

Если ф-ция вернула 0, то значит кончилось время ожидания
Иначе - ошибка

См. MSDN.


 
FireMan_Alexey ©   (2004-02-19 10:29) [2]

А если я заказал сразу все события, то как определить, что получилось приход данных, освобождение очереди или ошибка?
Может где-то есть флаги которые можно проанализировать?


 
Verg ©   (2004-02-19 10:35) [3]

FD_SET - ы кончено должны быть разными для каждого класса событий

var
 ReadSet,
 WriteSet,
 ExceptSet : TFDSet;
 TV:TTimeVal;
 Res : integer;

begin
 .................
 res := select(FD_SETSIZE , @ReadSet, @WriteSet, @ExceptSet, @TV);
 if Res > 0 then
 begin
   // Тут анализируем ***Set для каждого сокета.
 end else
   if Res< 0 then
      raise .........
..............
end;
end;


 
Digitman ©   (2004-02-19 12:25) [4]

вообще-то select() не оч удобен ..
правда, отказаться от его использования порой сложно, если гнездо инициализировано для работы в блок.режиме

если же имеется принципиальная возможность и необходимость работы с асинхронным транспортом, то лучше и удобней ф-ции WSAEnumNetworkEvents() для этой цели не выдумать : она сразу вернет в одном массиве все активные события транспорта и сбросит просигналивший ивент


 
Verg ©   (2004-02-19 13:22) [5]

Если говорить про сокеты в асинхронных режимах (WSAAsyncSelect или WSAEventSelect), то для них вообще select неприменима (бесполезна, has no effect).
А для сокетов в блокирующем или неблокирующем (FIONBIO) режимах она оказывается иногда лучше, чем делать поллинг, особенно в коснольных приложениях.


 
FireMan_Alexey ©   (2004-02-19 14:43) [6]

Вы правы, но я использую синхронный режим.
Т.к. нужно выполнять все в одном кодовом потоке и асинхронные сокеты не подходят.
Я просто тупанул с переменными. Считал, что можно сделать
так: Select(Socket_Count,@SS,@SS,@SS,@TV); используя только
одну переменную @SS, когда можно было три.
Огромное спасибо за помощь.


 
Verg ©   (2004-02-19 14:49) [7]


> Т.к. нужно выполнять все в одном кодовом потоке и асинхронные
> сокеты не подходят.



Эт-то вы очень сильно погорячиличь.

"Как, вы не любите кошек? Да вы просто их готовить не умеете!" :)


 
Digitman ©   (2004-02-19 15:15) [8]


> Verg ©   (19.02.04 14:49) [7]


цитата оч даже к месту была)


> нужно выполнять все в одном кодовом потоке и асинхронные
> сокеты не подходят.


ну смелей ! аргументируй ! думай вслух ! мы поправим те места, где у тебя каша из потоков и "асинхронности" в голове


 
FireMan_Alexey ©   (2004-02-20 18:36) [9]

Короче выглядит все таким образом:
Procedure MyThread.Execute
Begin
   {Синхронный коннект}
 Repeat
   {Здесь находится синхронные команды обработки сообщений}
 Until Terminated or CloseConnection;
   {Закрытие сообщения}
End;
Вобщем я по другому себе это не представляю!
Как можно в цикле обрабатывать асинхронные сообщения от сокетов,
ну кроме как просто запустить бесконечный цикл, а в обработчике
OnClose или как в TClientSocket.OnDisconnect выполнять
CloseConnection:=True;
Дело в том, что у меня может произойти ситуация, когда только начал коннектиться сокет к серверу и происходит ошибка, то в другом потоке уже может высвободиться память выделенная этому сокету. Поэтому постоянно происходят ошибки обращения к несуществующей(невыделенной) области памяти.
Я думал, что синхронный коннект и выделение для каждого коннекта своего потока будет более нормальной реализацией алгоритма.
но сталкнулся с проблемой определения событий FD_READ, FD_WRITE, FD_CLOSE в синхронных, но уже почти совсем разобратся с Вашей помощью! За что очень Вам благодарен.
Если я в чем-то не прав помогите разобраться!


 
Verrg   (2004-02-20 19:58) [10]

WSAEventSelect
MsgWatForMultimleObject......

Короче, потом......
Сегодня нас женщины поздравляли.... знаешь чем чем это заканчиватся...????
Вот и сейчас от клавы отрывают, .....


 
Verg ©   (2004-02-21 09:03) [11]

Для начала глянь вот это:

http://delphimaster.net/view/6-1075625924/


 
FireMan_Alexey ©   (2004-02-23 09:21) [12]

Попутный вопрос как определить значение ошибки в сокетах которые приходят после Select.
Я делал так:
Size:=SizeOf(Err);
getsockopt(Sock,Sol_Socket,SO_ERROR,PChar(@Err),Size);

В 98 работает в ХР выдает 0.
Может что-то не правильно сделал?


 
Verg ©   (2004-02-23 12:18) [13]

Именно после Select?

Summary: A socket will be identified in a particular set when select returns if:

readfds:

If listen has been called and a connection is pending, accept will succeed.
Data is available for reading (includes OOB data if SO_OOBINLINE is enabled).
Connection has been closed/reset/terminated.
writefds:

If processing a connect call (nonblocking), connection has succeeded {на это должны обратить внимание даже те, кто использует асинхронные сокеты и пытается работать с соединением в событии OnConnect, вместо OnWrite}.
Data can be sent.
exceptfds:

If processing a connect call (nonblocking), connection attempt failed.
OOB data is available for reading (only if SO_OOBINLINE is disabled).



> Я делал так:
> Size:=SizeOf(Err);
> getsockopt(Sock,Sol_Socket,SO_ERROR,PChar(@Err),Size);
> В 98 работает в ХР выдает 0.
> Может что-то не правильно сделал?


Не знаю. С виду все верно, окромя типа переменной Err - д.б. integer.



Страницы: 1 вся ветка

Текущий архив: 2004.04.25;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.027 c
1-1081162182
Layner
2004-04-05 14:49
2004.04.25
Мастера! Можно ли стандартные хинты сделать вечными?


1-1081146749
an-na2002
2004-04-05 10:32
2004.04.25
замена , на .


14-1080788841
Kolyan
2004-04-01 07:07
2004.04.25
ASSEMBLER


1-1081348339
RainKM
2004-04-07 18:32
2004.04.25
Компоненти для создания проги типа Експлорер!!!!!


1-1081217402
GreatMaster
2004-04-06 06:10
2004.04.25
Поддержка нац. языков при вводе текста в контрол - как?