![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
FD_READ, FD_WRITE и другие... [D7, WinXP]
Новичек © (2005-06-02 22:22:00)Уважаемые Мастера, столкнулся вот с какой проблемой.
Программирую сокеты на WSA (WinSocketApi), использую библиотеку WinSock2.
(Дабы предупредить некоторые ответы, скажу, что MSDN читал очень внимательно).
1.Так вот, событие FD_CONNECT на клиенте у меня никогда не происходит. Как я понял, оно применимо только к серверам.
2.Непонятно, когда всё-таки на стороне клиента происходит событие FD_WRITE? Непосредственно перед WSASend?
Спасибо.
Новичек (2005-06-05 12:46:00) [1]
> Ученик
Спасибо, дорогой :-) Я понял!!! Заработало!!!
Новичек (2005-06-05 12:40:00) [2]
> Ученик
Эх, я уж наизусть это выучил :-) Может, знаешь, как правильно сделать?
Ученик (2005-06-05 12:22:00) [3]>Новичек © (05.06.05 12:06) [5]
int WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
);
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, *LPWSANETWORKEVENTS;
Новичек (2005-06-05 12:06:00) [4]
> Вроде, в вызове WSAEnumNetworkEvents беда с параметрами
Думаешь, массив виноват? Не думаю... Если присвоить переменной pEvents тип WSAEVENT (либо просто Cardinal), то ничего не изменится.
Ученик (2005-06-05 11:55:00) [5]>Новичек © (05.06.05 09:32) [3]
Вроде, в вызове WSAEnumNetworkEvents беда с параметрами
Новичек (2005-06-05 09:32:00) [6]Вот код:
program Project1;
uses
WinSock2, ScktComp, SysUtils, Dialogs;
var
WSAData: TWSAData;
ErrorCode: Integer;
MySocket: TSocket;
MySocketAddr: TSockAddr;
pEvents: array [0..WSA_MAXIMUM_WAIT_EVENTS] of WSAEVENT;
Buf: array [0..2048] of Char;
begin
//Инициализируем библиотеку winsock2
ErrorCode := WSAStartup($0101, WSAData);
if ErrorCode <> 0 then raise ESocketError.Create('WSAStartup');
//Создаём событие, которое мы хотим отслеживать на данном сокете
pEvents[0] := WSACreateEvent();
//Создаём сокет
MySocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
//Подготовим память под структуру адреса сокета
FillChar(MySocketAddr, SizeOf(MySocketAddr), 0);
//Заполняем структуру адреса
MySocketAddr.sin_family := AF_INET;
MySocketAddr.sin_addr.s_addr := Inet_Addr('10.42.1.47');
MySocketAddr.sin_port := htons(5001);
{Свяжем события pEvents с сокетом, события которого мы хотим контролировать и обрабатывать.}
WSAEventSelect(MySocket, pEvents[0], FD_CONNECT);
//Попробуем подконнектиться к серверу
Connect(MySocket, @MySocketAddr, SizeOf(MySocketAddr));
//Вызываем следующую функцию, ожидающую наступления событий. WSAWaitForMultipleEvents(1, @pEvents, FALSE, WSA_INFINITE, FALSE);
//Выясним, какое именно событие произошло на сокете:
WSAEnumNetworkEvents(MySocket, pEvents[0], @pEvents);
case pEvents[0] of
1: ShowMessage('Готов читать');
2: ShowMessage('Готов писать');
16: ShowMessage('Подконнектился...');
end;
CloseSocket(MySocket);
end.
Нет ни одного event'a :-(
Что я не так сделал? Помогите, пожалуйста, разобраться.
Digitman (2005-06-03 08:21:00) [7]
> MSDN читал очень внимательно
не факт.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsaeventselect_2.asp
> событие FD_CONNECT на клиенте у меня никогда не происходит.
так ты поди WSAEventSelect/WSAAsyncSelect вызываешь уже после connect()..
> Как я понял, оно применимо только к серверам
к серверам оно как раз не применимо.
к ним применимо FD_ACCEPT
> когда всё-таки на стороне клиента происходит событие FD_WRITE?
минимум однократно сразу за FD_CONNECT или FD_ACCEPT и всякий раз после освобождения внутреннего буфера передачи, о занятости которого ф-ция [WSA]Send сообщила отказом с кодом WSAEWOULDBLOCK
Новичек (2005-06-03 07:44:00) [8]Никто не знает? Жаль... Придется экспериментальным путем выяснять :-)