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