Форум: "Сети";
Текущий архив: 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