Текущий архив: 2006.09.24;
Скачать: CL | DM;
ВнизСостояние сокета winsock Найти похожие ветки
← →
KASioZ (2006-05-06 02:31) [0]Здравствуйте уважаемые программисты!
У меня есть указатель на не-блокирующий сокет полученный при помощи вызова функции socket (winsock.pas)
Как я могу определить его статус (connected/disconnected или если возможно то и статус connecting) в любой момент выполнения моей программы?
Помогите пожалуйста!
Очень надо!
А так же если это возможно определить кол-во байт доступных для чтения на данный момент времени (не получая их)
Всё это есть в компоненте Fundamentals Sockets
но исполльзовать их я не могу изза ограниченного размера моего конечного приложения
← →
Сергей М. © (2006-05-06 08:53) [1]
> не-блокирующий сокет полученный при помощи вызова функции
> socket
Вызов socket() приводит к созданию как раз блокирующего гнезда.
> Как я могу определить его статус
Никак.
О контроле за текущим статусом ты должен позаботиться сам.
В блок.режиме:
- статус connected гнездо получает после успешного выполнения connect()
- статус disconnected гнездо получает после успешного выполнения closesocket()
- статус connecting в блок.режиме имеет смысл разве что на время выполнения connect()
В неблок.режиме:
- статус connected гнездо получает после успешного выполнения connect() и последующего определения факта writability=True (см. select), либо по факту события FD_CONNECT (см. WSAAsyncSelect, WSAEventSelect)
- статус disconnected гнездо получает после успешного выполнения closesocket() (при использовании нотификаций - как реакции на событие FD_CLOSE (см. WSAAsyncSelect, WSAEventSelect)
> определить кол-во байт доступных для чтения на данный момент
> времени
Никак.
Но ioctlsocket(FIONREAD) поможет оценить макс.размер данных, находящихся в очереди на прием на момент вызова ф-ции
← →
KASioZ (2006-05-06 09:13) [2]>> не-блокирующий сокет полученный при помощи вызова функции
>> socket
>Вызов socket() приводит к созданию как раз блокирующего гнезда.
А как же тогда создать не блокирующий сокет ?
Неужели не функцией ioctlsocket ?
Которая вызывается как раз таки после создания сокета фун-ей socket()
>- статус disconnected гнездо получает после успешного выполнения closesocket()
а если сокет закрыл удаленный сервер ?
>- статус disconnected гнездо получает после успешного выполнения closesocket() (при использовании нотификаций - как реакции на событие FD_CLOSE (см. WSAAsyncSelect, WSAEventSelect)
Использовать асинхронный сокет я не могу, т.к в программе нет и не может быть никаких окон (не видимых и видимых).
← →
Сергей М. © (2006-05-06 10:25) [3]
> как же тогда создать не блокирующий сокет ?
Никак.
Гнездо создается в блокирующем режиме и после этого переводится в неблокирующий одной из ф-ций ioctlsocket(), WSAAsyncSelect(), WSAEventSelect(). Все это достаточно подробно изложено в станд.справке. Если с буржуйским языком проблема, то обо всем том же самом можно почитать на русском, например, в http://book.itep.ru
> если сокет закрыл удаленный сервер ?
см. событие FD_CLOSE
> Использовать асинхронный сокет я не могу, т.к в программе
> нет и не может быть никаких окон (не видимых и видимых).
WSAEventSelect не требует никаких окон.
Да и непонятно, чем окна так насолили ..
← →
KASioZ (2006-05-06 10:54) [4]Хорошо я вижу что в моём случае можно пойти только путём асинхронности.
Но тогда при 1ых же проведенных мною опытах я обнаружил некую проблему.
Событие FD_CONNECT вызывается если даже не удалось установить соединения с сокетом.
Как быть в этом случае ?
← →
Сергей М. © (2006-05-06 11:00) [5]
> в моём случае можно пойти только путём асинхронности
Из условий задачи это не очевидно.
Ничто не мешает использовать и блок.режим.
> Событие FD_CONNECT вызывается если даже не удалось установить
> соединения с сокетом
Этого не может быть.
Цитата из док-ции:
FD_CONNECT Want to receive notification of completed connection
← →
KASioZ (2006-05-06 11:10) [6]Что же, я так понимаю что без асинхронности мне не обойтись в данном случае.
Но при проведении мною очередных опытов я обнаружил что FD_Connect вызывается и в случае неуспешного соединения.
Как тогда проверить успешно подключились или нет?
Попробовал так же почерпнуть информацию с сайта http://book.itep.ru
который вы мне дали, но там научное изложение которое мне никогда понятно небыло.
Думаю это большая ошибка автора за такое изложение.
Читал как то Джефри Рихтера, вот там действительно хорошее и понятное изложение материала с тщательно разобранными примерами, а не только одна грузящяя и не понятная теория.
Такую информацию можно только использовать в качестве краткого справочного пособия, но ни как не для самостоятельного обучения.
← →
Сергей М. © (2006-05-06 11:20) [7]
> без асинхронности мне не обойтись в данном случае
Можно и синхронно, можно и асинхронно - в твоей задаче я не вижу ничего, что бы однозначно требовало асинхронность.
> FD_Connect вызывается и в случае неуспешного соединения
Нет, не вызывается.
> там научное изложение которое мне никогда понятно небыло
Процитируй фрагмент непонятого тобой "научного изложения" ..
> большая ошибка автора за такое изложение
Не думаю, что столь велика проблема найти в Сети "изложение на огурцах" того же самого.
> информацию можно только использовать в качестве краткого
> справочного пособия
Инженер обязан уметь пользоваться справониками.
← →
Polevi © (2006-05-06 11:56) [8]>KASioZ (06.05.06 11:10) [6]
ай яй какие нехорошие неправильно излагают
готов помочь 100$ час
← →
KASioZ (2006-05-06 12:17) [9]
> Можно и синхронно, можно и асинхронно - в твоей задаче я
> не вижу ничего, что бы однозначно требовало асинхронность.
>
Ладно если быть конкретнее то скажу что мне надо сделать.
Моя программа должна быть очень маленькой (поэтому VCL отпадают) в размере и должна она выполнять PHP скрипты на удалённом WEB сервере с использованием протокола HTTP/1.1 (Connection: close).
Поскольку время выполнения скрипта в данном случае абсолютно не известно то определить завершение выполнения скрипта можно только когда сервер сам закроет соединение.
Для этого мне и необходимо определять статус сокета.
Т.е прерывать цикл приема данных при закрытии соединения сервером.
Сейчас у меня прием тела страницы реализован так:repeat
select(0, @fds, nil, nil, @tv);
len:=recv(s,buf,SizeOf(buf),0);
if len > 0 then BlockWrite(F, buf, len);
until len = 0;
Но как я уже говорил это возможно только для HTML страниц, PHP скрипт может выполняться и час!
А значение переменной tv я не могу ставить слишком большим, ведь вдруг пользователь вообще из интернета вышел, тогда этот простой будет крайне недопустим в моей программе.
Может есть вариант написать свою мини-сокет библиотеку, и сделать это примерно так:
uses MyTCPClientLib;
...
MySocket:=TMyTCPClient.Create;
MySocket.BMode:=sm_nonblock;
MySocket.Connect("www.mysite.com", 80);
while MySocket.Connecting do Application.ProcessMessages;
if not MySocket.Connected then
begin
ShowMessage("Connection error");
Exit;
end;
while not MySocket.ReadyToSend do Application.ProcessMessages;
MySocket.Send(Request, SizeOf(Request));
repeat
while MySocket.AvailableToRead = 0 do Application.ProcessMessages;
len:=MySocket.Receive(buf, SizeOf(buf));
BlockWrite(F, buf, len);
until not MySocket.Connected;
Если бы было возможно реализовать такой пример без использования VCL то было бы всё супер-пупер!
← →
Сергей М. © (2006-05-06 12:43) [10]Причем здесь HTTP, PHP и прочие прикладные дела ?
Речь идет о грамотной организации транспорта, а не о прикладном уровне ...
Где у тебя анализ результата вызова ф-ции select() ?
Почему не обрабатываешь ситуацию Len = 0 и Len < 0 ?
← →
KASioZ (2006-05-06 14:44) [11]Я вообще так сильно запутался что теперь вообще уже ничего не понимаю.
Вы мне скажите как я могу определить что сервер закрыл сокет ?
Не используя WSAAsynSelect ?
Вы же сказали это возможно ?
>Можно и синхронно, можно и асинхронно - в твоей задаче я
>не вижу ничего, что бы однозначно требовало асинхронность.
>
← →
Сергей М. © (2006-05-06 15:29) [12]
> Не используя WSAAsynSelect
Говорю же - WSAEventSelect()...
Ее использование подразумевает как раз асинхронный неблокирующий режим, и окна при этом не нужны никакие.
> как я могу определить что сервер закрыл сокет ?
> Вы же сказали это возможно ?
Конечно возможно.
Когда партнер закрывает соединение по своей инициативе, возникает событие FD_CLOSE, обнаружить которое можно с пом. WSAEnumNetworkEvents при условии использования для работы в неблок.режиме ф-ции WSAEventSelect().
← →
KASioZ (2006-05-06 15:42) [13]А не поделитесь ли URL"ами русскоязычными ?
Где можно побольше инфы про этот способ прочитать ?
Желательно чтобы было больше примеров с объяснениями чем теории.
И я вижу что поддержка эта начинается с Windows 2000.
Но ведь не может такого быть чтобы в Windows 95, 98, ME, NT 4.0 небыло возможным разрешить поставленную задачу.
← →
Сергей М. © (2006-05-06 16:09) [14]
> не поделитесь ли URL"ами русскоязычными ?
У меня таковые не имеются за ненадобностью.
Но, думаю, их найдется великое множество, если повнимательней погуглить.
> вижу что поддержка эта начинается с Windows 2000
С чего бы вдруг ?
Цитата из MSDN в справке к WSAEventSelect:
Requirements
Client
Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 3.51 and later, Windows Me, Windows 98, or Windows 95.
Server
Requires Windows Server "Longhorn", Windows Server 2003, Windows 2000 Server, or Windows NT Server 3.51 and later.
← →
KASioZ (2006-05-06 16:26) [15]Огромное спасибо за помощь чайнику!
И за потраченное н меня время!
← →
Сергей М. © (2006-05-06 16:41) [16]незафто
Страницы: 1 вся ветка
Текущий архив: 2006.09.24;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.045 c