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

Вниз

Состояние сокета 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.041 c
1-1155530058
dellam
2006-08-14 08:34
2006.09.24
Resize


2-1157371407
Ефимыч
2006-09-04 16:03
2006.09.24
Подскажите, как сделать, чтоб jpeg не компилировался в exe-шник?


15-1157452753
rerfhtre
2006-09-05 14:39
2006.09.24
tcpdump: dmp files


15-1157625317
Parus
2006-09-07 14:35
2006.09.24
Созвездия


6-1146868280
KASioZ
2006-05-06 02:31
2006.09.24
Состояние сокета winsock





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский