![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
WSAWaitForMultipleEvents для однонитевого сервера [D6, XP]
Евгений07 © (2011-09-09 16:14:00)Уважаемые дельфийцы!
Есть ли примеры использования WSAWaitForMultipleEvents для запуска процедуры приема и обработке данных однонитевым сервером от единственного клиента ( WinSock2 )
Событие об отправке данных серверу через PostMessage, были случаи, терялись.
Номер сообщения получен из RegisterWindowMessage.
Возможно, клиент и сервер будут на разных компах, тогда PostMessage отпадает.
Заводить процесс только для WSAWaitForMultipleEvents для единственного клиента сервера не хочется, нет практики, потребности и времени.
Как вариант есть еще таймер
Где посоветуете копать?
Евгений07 (2011-09-13 16:53:00) [1]Вариант (13.09.11 12:39) [43]
СПАСИБО!
Читай "Программирование в сетях Windows" Джонса и Оланда.
СПАСИБО!
Нашел. Автор исходника наверное пошутил, для сервера ловил FD_CONNECT
Книга = супер
Еще раз спасибо
Вариант (2011-09-13 12:39:00) [2]
> Евгений07 (13.09.11 10:45) [37]
А твой сервер и не должен видеть клиента, ибо не как сервер он у тебя написан. Читай "Программирование в сетях Windows" Джонса и Оланда. Там пример кода сервера есть для EventSelect модели да и модель select описана.
Сергей М. (2011-09-13 12:38:00) [3]При знаниях на уровне "фурычит - не фурычит" затея с реализацией клиента и сервера непосредственно на WinSock выглядит довольно глупой.
Чем не устроили готовые компоненты - совершенно не понятно)
Евгений07 (2011-09-13 12:15:00) [4]в первую очередь не надо вызывать VCL из не-VCL потока.
я про Form1.Memo1.Lines.Add.
Вырубил. = 0
Вариант (2011-09-13 11:37:00) [5]
> Вариант (13.09.11 11:32) [39]
Не TServerSocket, a TClientSocket
Вариант (2011-09-13 11:32:00) [6]
> Евгений07 (13.09.11 10:45) [37]
Возьми TServerSocket на закладке интернет и не мучайся, будет у тебя все вызываться в основном потоке. И почитай хелп по кмопонентам и обязательно литературу по TCP и потокам. Все равно надо это сделать, почему не сделать это сейчас.
RWolf (2011-09-13 11:00:00) [7]в первую очередь не надо вызывать VCL из не-VCL потока.
я про Form1.Memo1.Lines.Add.
Евгений07 (2011-09-13 10:45:00) [8]Доброго времени, мастера!
Нашел пожирателя ЦП - это клиент, не получавший подтверждения
Evgeny V (12.09.11 14:26) [32]
Если работа идет в разных потоках - то это тоже ошибка
Сейчас переписал SocketBar в поток серверной нити
Сервер не видит подключения клиента
Клиент сделан на WinSock
Len := SelectFDSet;
Len := connect (Sockett, Addr, SizeOf(TSockAddr) ) ;
, , ,
if FD_IsSet(Sockett, FDSetR) or FD_IsSet(Sockett, FDSetW)
then begin
Res := PostMessage(wnd, WM_PewForArx, 1, 2); // открытка подключения = принята
if not Res then
OperSocet := 1 //сбой
else begin
OperSocet := 10; // работа = работает
end;
end;
if (OperSocet >= 10) // ...
then begin //
Len := SelectFDSet;
if FD_IsSet(Sockett, FDSetR) then begin
// = здесь тишина
end;
end;
Сервер не видит коннекта
hEvent:= WSACreateEvent;
if hEvent = WSA_INVALID_EVENT then Exit;
Flags := SOCKET_ERROR;
Flags := WSAEventSelect(Sockett, hEvent, FD_WRITE or FD_READ or FD_CONNECT or FD_CLOSE);
if Flags = SOCKET_ERROR then Exit
else while True do begin
Event:= WSAWaitForMultipleEvents(1, @hEvent, False, WSA_INFINITE, False); //
if (Event = WSA_WAIT_FAILED) then begin
Break;
end;
if (WSAEnumNetworkEvents(Sockett, hEvent, @NetworkEvents) = SOCKET_ERROR)
then begin
Form1.Memo1.Lines.Add('WSAEnumNetworkEvents() failed with error: ' + IntToStr(WSAGetLastError));
Break;
end;
WSAResetEvent(hEvent);
if ((NetworkEvents.lNetworkEvents and FD_CONNECT)<>0) then begin
if (NetworkEvents.iErrorCode[FD_CONNECT_BIT]<>0) then begin
Form1.Memo1.Lines.Add('FD_CONNECT failed with error:' + IntToStr(NetworkEvents.iErrorCode[FD_CONNECT_BIT]));
Break;
end else begin
Len := SizeOf(TSockAddr);
AcceptedSock := Accept(Sockett, Addr, Len);
if AcceptedSock = Invalid_Socket then begin
Form1.Memo1.Lines.Add('FD_CONNECT failed with error:' + IntToStr(NetworkEvents.iErrorCode[FD_CONNECT_BIT]));
Break;
end else begin
OperSocet := 10;
end;
Form1.Memo1.Lines.Add('Connect socket: ' + IntToStr(Sockett));
end;
end;
Может я зря пробую подключать коннект в дополнительной нити?
Если подключать коннект в основной нити, то что то фурычит.
Тогда как ждать коннект?
Или в клиенте делать WSAConnect?
Евгений07 (2011-09-12 20:10:00) [9]Совет не поменять WSAWaitForMultipleEvents на голову принят
Сергей М. (2011-09-12 20:05:00) [10]Ну точно белочка)
DiamondShark (2011-09-12 19:53:00) [11]……………………………………
……………………………………
……………………………………
……………………………………..________
………………………………,.-‘”……………….“~.,
………………………..,.-”……………………………..“-.,
…………………….,/………………………………………..”:,
…………………,?………………………………………………\,
………………./…………………………………………………..,}
……………../………………………………………………,:`^`..}
……………/……………………………………………,:”………/
…………..?…..__…………………………………..:`………../
…………./__.(…..“~-,_…………………………,:`………./
………../(_….”~,_……..“~,_………………..,:`…….._/
……….{.._$;_……”=,_…….“-,_…….,.-~-,},.~”;/….}
………..((…..*~_…….”=-._……“;,,./`…./”…………../
…,,,___.\`~,……“~.,………………..`…..}…………../
…………(….`=-,,…….`……………………(……;_,,-”
…………/.`~,……`-………………………….\……/\
………….\`~.*-,……………………………….|,./…..\,__
,,_……….}.>-._\……………………………..|…………..`=~-,
…..`=~-,_\_……`\,……………………………\
……………….`=~-,,.\,………………………….\
…………………………..`:,,………………………`\…………..__
……………………………….`=-,……………….,%`>–==“
…………………………………._\……….._,-%…….`\
……………………………..,
Evgeny V (2011-09-12 14:30:00) [12]И дальше, а кто собственно заполняет NetworkEvents (где WSAEnumNetworkEvents )?
Evgeny V (2011-09-12 14:26:00) [13]Кстати еще - как сочетается
> Form1.SocketBar
и
> Пока проверил версию с потоком
Если работа идет в разных потоках - то это тоже ошибка
Evgeny V (2011-09-12 14:16:00) [14]Да и анализа на WSA_WAIT_FAILED нет
Evgeny V (2011-09-12 14:15:00) [15]
> Евгений07 (12.09.11 14:05) [29]
WSA_INFINITE - ждать пока не произойдет событие.
А прога у тебя или скопирована кусками или с ошибками так и была. Ты создал событие, которое должно сбрасываться вручную.... Ты получил сетевое событие, не сбросил и снова вошел в цикл ожидания, а событие-то в сигнальном состоянии еще/уже, значит сразу вывалился и опять все то же самое по бесконечному циклу без перерыва(где WSAResetEvent). Ошибка однако.
Евгений07 (2011-09-12 14:05:00) [16]Значение WSA_INFINITE не посмотрел, но задал 1000 мс те же 50 %
Евгений07 (2011-09-12 13:52:00) [17]Взял стандартную прогу с инета
procedure SocketProc;
var
hEvent,Event: WSAEVENT;
NetworkEvents: TWSANetworkEvents;
begin
//==============================================================================
hEvent:= WSACreateEvent;
if hEvent = WSA_INVALID_EVENT then Exit;
if WSAEventSelect(AcceptedSock, hEvent,
FD_CONNECT or FD_WRITE or
FD_READ or FD_CLOSE) = SOCKET_ERROR then Exit
else begin
while True do begin
Event:= WSAWaitForMultipleEvents(1, @hEvent, False, WSA_INFINITE, False); //
if ((NetworkEvents.lNetworkEvents and FD_READ)<>0) then begin
if (NetworkEvents.iErrorCode[FD_READ_BIT]<>0) then begin
WriteLn('FD_READ failed with error: ' + IntToStr(NetworkEvents.iErrorCode[FD_READ_BIT]));
Break;
end else begin
Form1.SocketBar; // здесь вызов рабочий, правда через селект, простой код
end;
end;
У меня ожидания обычно до минуты
terminal.exe 50 - 54 % времени ЦП
Если запуск вручную кнопкой, Цп 1 - 0 %, запуск через PostMessage Цп 1 - 0 %
Evgeny V (2011-09-12 13:46:00) [18]
> Inovet © (12.09.11 13:38) [26]
Если только он не задал интервал ожидания 0 например. Вываливается сразу и грузит систему вечным опросом с маленьким интервалом.
Но партизаны строк проблемного кода не дают.....
Inovet (2011-09-12 13:38:00) [19]> [24] Евгений07 (12.09.11 13:02)
Она на то и Wait, чтобы не жрать ничего до события, как и таймер до заданного интервала.
Evgeny V (2011-09-12 13:26:00) [20]
> Евгений07 (12.09.11 13:02) [24]
В режиме ожидания WSAWaitForMultipleEvents ничего не жрет. Я использовал в своих программах и WsaAsyncSelect и WSAWaitForMultipleEvents, сама функция(WSAWaitForMultipleEvents) в режиме ожидания не жрет ничего. Проблема в коде дальнейшем.