Текущий архив: 2005.10.02;
Скачать: CL | DM;
Вниз
FD_READ, FD_WRITE и другие... Найти похожие ветки
← →
Новичек © (2005-06-02 22:22) [0]Уважаемые Мастера, столкнулся вот с какой проблемой.
Программирую сокеты на WSA (WinSocketApi), использую библиотеку WinSock2.
(Дабы предупредить некоторые ответы, скажу, что MSDN читал очень внимательно).
1.Так вот, событие FD_CONNECT на клиенте у меня никогда не происходит. Как я понял, оно применимо только к серверам.
2.Непонятно, когда всё-таки на стороне клиента происходит событие FD_WRITE? Непосредственно перед WSASend?
Спасибо.
← →
Новичек © (2005-06-03 07:44) [1]Никто не знает? Жаль... Придется экспериментальным путем выяснять :-)
← →
Digitman © (2005-06-03 08:21) [2]
> 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-05 09:32) [3]Вот код:
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 :-(
Что я не так сделал? Помогите, пожалуйста, разобраться.
← →
Ученик (2005-06-05 11:55) [4]>Новичек © (05.06.05 09:32) [3]
Вроде, в вызове WSAEnumNetworkEvents беда с параметрами
← →
Новичек © (2005-06-05 12:06) [5]
> Вроде, в вызове WSAEnumNetworkEvents беда с параметрами
Думаешь, массив виноват? Не думаю... Если присвоить переменной pEvents тип WSAEVENT (либо просто Cardinal), то ничего не изменится.
← →
Ученик (2005-06-05 12:22) [6]>Новичек © (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:40) [7]
> Ученик
Эх, я уж наизусть это выучил :-) Может, знаешь, как правильно сделать?
← →
Новичек © (2005-06-05 12:46) [8]
> Ученик
Спасибо, дорогой :-) Я понял!!! Заработало!!!
Страницы: 1 вся ветка
Текущий архив: 2005.10.02;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.058 c