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

Вниз

Вопрос по WSA (WinSocket API).   Найти похожие ветки 

 
Новичек ©   (2005-06-21 14:09) [0]

Уважаемые знатоки, понадобилось мне написать в Delphi программку для работы с сокетами на низком уровне. Написать-то написал, да вот сомнения меня терзают - всё ли там в порядке?
Вот код:

procedure MyProcedure;
var
 vSocket: TSocket;
 vSockAddr: TSockAddr;
 aBuf: array [0..2048] of char;
 pEvent: WSAEVENT;
 ConnectError: Integer;
 NetworkEvents: TWSANetworkEvents;
 
 procedure SendStr(Str: string);
 var
  C: char;
 begin
   while (length(Str) > 0) do
     begin
       C := Str[1];
       delete(Str, 1, 1);
       Send(vSocket, C, 1, 0);
     end;
 end;
begin
 pEvent := WSA_INVALID_EVENT;
 pEvent := WSACreateEvent();
 FillChar(vSockAddr, SizeOf(TSockAddr), 0);
 vSockAddr.sin_family := AF_INET;
 vSockAddr.sin_port := htons(5000);
 vSockAddr.sin_addr.S_addr := inet_addr("127.0.0.1");
 vSocket := WinSock2.Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
 if vSocket = INVALID_SOCKET then Halt(1);
 WSAEventSelect(vSocket, pEvent, FD_READ);
 WinSock2.Connect(vSocket, @vSockAddr, SizeOf(vSockAddr));
//Дожидаюсь разрешения на чтение:
 WSAWaitForMultipleEvents(1, @pEvent, FALSE, WSA_INFINITE, FALSE);
 WSAResetEvent(pEvent);
//Принимаю стартовый пакет сервера и обнуляю буфер приема:
 Recv(vSocket, aBuf, SizeOf(aBuf), 0);
 aBuf := "";
//Дожидаюсь разрешения на чтение:
 WSAWaitForMultipleEvents(1, @pEvent, FALSE, WSA_INFINITE, FALSE);
//Принимаю приветствие сервера, заканчивающееся символом "<"и обнуляю буфер приема:
//символом "<":
 repeat
   Recv(vSocket, aBuf, SizeOf(aBuf), 0);
 until Pos("<", aBuf) <> 0;
 aBuf := "";
 WSAResetEvent(pEvent);
 SendStr("Hello, Dolly" + #13#10);
 WSAWaitForMultipleEvents(1, @pEvent, FALSE, WSA_INFINITE, FALSE);
//Здесь я должен дождаться ответа сервера:
 repeat
   Recv(vSocket, aBuf, SizeOf(aBuf), 0);
 until Pos("Well, hello", aBuf) <> 0;
 aBuf := "";
 WSAResetEvent(pEvent);
 SendStr("Good by" + #13#10);
 WSAResetEvent(pEvent);
 CloseSocket(vSocket);
 WSACleanup;
end;

Меня интересует, а правильно ли я распоряжаюсь Event"ами? И как запрограммировать больше событий - для каждого делать CreateEvent?
Спасибо.


 
Digitman ©   (2005-06-21 14:21) [1]


> правильно ли я распоряжаюсь Event"ами


думаю, неправильно.

все преимущества асинхронной работы с гнездом с использованием событийного механизма нотификаций  этим кодом ты свел на нет, реализовав в конечном итоге обычный синхронный алгоритм

кр. того, создавая ивент-объект ты становишься ответственным за его уничтожение, коего в твоем коде нет


 
Новичек ©   (2005-06-21 14:24) [2]

Эх, я и подозревал нечто подобное :-( Буду переделывать.
Спасибо.


 
Digitman ©   (2005-06-21 15:05) [3]


> как запрограммировать больше событий - для каждого делать
> CreateEvent?


зачем ?

в справке же черным по белому написано :

to associate an event object with both reading and writing network events, the application must call WSAEventSelect with both FD_READ and FD_WRITE, as follows:

rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);
 

It is not possible to specify different event objects for different network events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE network event will be associated with hEventObject2:

rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad
 

To cancel the association and selection of network events on a socket, lNetworkEvents should be set to zero, in which case the hEventObject parameter will be ignored.


 
Polevi ©   (2005-06-21 15:49) [4]

да не будет это работать, где анализ результатов вызова ф-ий


 
Новичек ©   (2005-06-21 16:12) [5]

Наверное, следует сделать как-то так:


WSAEventSelect(vSocket, pEvent, FD_READ or FD_WRITE or FD_CONNECT);
...
 WSAEnumNetworkEvents(vSocket, pEvent, @NetworkEvents);

 case NetworkEvents.lNetworkEvents of
   FD_CONNECT: PostMessage(MainWnd, WM_MESSAGE, 0, 2);
   FD_READ: PostMessage(MainWnd, WM_MESSAGE, 0, 3);
   FD_WRITE: PostMessage(MainWnd, WM_MESSAGE, 0, 4);
   else PostMessage(MainWnd, WM_MESSAGE, 0, 5);
 end;


PostMessage взят, разумеется, только для примера.
Правильно я понял?


 
Digitman ©   (2005-06-21 17:11) [6]


> Новичек ©   (21.06.05 16:12) [5]


да, WSAEnumNetworkEvents() - не худший способ "разбора", даже порой лучше и удобнее (удобнее хотя бы потому что явный WSAResetEvent не требуется)


 
Новичек ©   (2005-06-21 17:13) [7]

Так-с, дело сдвинулось :-) Появилось направление копания :-)
Спасибо большое!
(Будете в Новороссийске - пиво с меня :-) )


 
Digitman ©   (2005-06-21 17:47) [8]


> Новичек ©   (21.06.05 17:13) [7]


а як же ж ?)

разумеется - с тебя)


 
Digitman ©   (2005-06-21 17:59) [9]

только не забывай , что в ряде случаев при "разборе" с пом. WSAEnumNetworkEvents() можно и должно анализировать возвращаемый ей не только массив кодов событий, но и сопутствующий массив кодов ошибок соотв.событий

иначе рано или поздно вляпаешься по самое нехочу


 
Новичек ©   (2005-06-21 18:08) [10]

Ага, понял. Учту, спасибо.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2005.10.09;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.014 c
4-1123692913
Bios_
2005-08-10 20:55
2005.10.09
Удаление пустого каталога


14-1127292597
vajo
2005-09-21 12:49
2005.10.09
Тормоза в винде


14-1127154468
palva
2005-09-19 22:27
2005.10.09
Поговорим о музыке


1-1127047828
MBoris
2005-09-18 16:50
2005.10.09
Word Application


2-1125055920
KyRo
2005-08-26 15:32
2005.10.09
Как отслеживать первую запись ?





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