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

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

WinSock.Select [D6, Win95/98, WinXP]


FireMan_Alexey ©   (2004-02-12 09:34:00) 

Ув. мастера прошу не подскажите пожалуйста где можно прочитать
как функция 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-23 12:18:00) [1]

Именно после 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.


FireMan_Alexey   (2004-02-23 09:21:00) [2]

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

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


Verg   (2004-02-21 09:03:00) [3]

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

http://www.delphimaster.ru/cgi-bin/forum.pl?id=1075625924&n=4


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

WSAEventSelect
MsgWatForMultimleObject......

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


FireMan_Alexey   (2004-02-20 18:36:00) [5]

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


Digitman   (2004-02-19 15:15:00) [6]


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


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


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


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


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


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



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

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


FireMan_Alexey   (2004-02-19 14:43:00) [8]

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


Verg   (2004-02-19 13:22:00) [9]

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


Digitman   (2004-02-19 12:25:00) [10]

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

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


Verg   (2004-02-19 10:35:00) [11]

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;


FireMan_Alexey   (2004-02-19 10:29:00) [12]

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


Verg   (2004-02-12 10:52:00) [13]


> или каждый раз нужно проверять отдельно
>
> 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.


Наверх

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