Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.035 c
1-1081586948
Insert
2004-04-10 12:49
2004.04.25
Проигрывание *.mov


1-1081164502
d_oleg
2004-04-05 15:28
2004.04.25
Странное зависание при ShowModal из DLL


3-1080551734
Iddqd
2004-03-29 13:15
2004.04.25
Дни недели


8-1073224124
Demian3797
2004-01-04 16:48
2004.04.25
Векторная графика


1-1081146956
Comp
2004-04-05 10:35
2004.04.25
Поиск шрифта





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский