Проблема с WSAAccept
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.217.37] |
|
|
Соблюдайте общие правила форума
MSDN Library
FAQ раздела
Поиск по разделу
Как правильно задавать вопросы
Проблема с WSAAccept
|
Сообщ.
#1
,
|
|
|
|
День добрый , подскажите, что не так делаю...
При выполнении DoAccept (разрешение на подключение клиента) даже не входит в Callback-функцию, а после выполнения DoAccept вообще вываливается "аккесс виол.." Сокет неблокирующий, DoAccept пытаюсь выполнить по сигналу эвента FD_ACCEPT, все (создание сокета,прослушивание и ожидание сигналов) делается в отдельном потоке, ф-ю CallBackAccept больше нигде не определял.. ![]() ![]() function CallBackAccept(lpCallerId: LPWSABUF; lpCallerData : LPWSABUF; lpSQOS,lpGQOS : LPQOS; lpCalleeId,lpCalleeData : LPWSABUF; g : GROUP; dwCallbackData : DWORD ) : Integer; stdcall; begin Result:=CF_Accept; end; function TClientsEventsThread.DoAccept:integer; var tmpSocket: TSocket; i:integer; begin i:=SizeOf(FSockAddrIn); Result:=0; tmpSocket:=WSAAccept(FSocket, FSockAddrIn, @i, CallBackAccept, 1); if tmpSocket=SOCKET_ERROR then begin Result:=WSAGetLastError; end; end; Добавлено всем спасибо, разобрался... надо было: tmpSocket:=WSAAccept(FSocket, @FSockAddrIn, @i, CallBackAccept, 1); и еще пришлось соответственно исправлять winsock2.pas: function WSAAccept( s : TSocket; addr : PSockAddr; addrlen : PInteger; lpfnCondition : LPCONDITIONPROC; dwCallbackData : DWORD ): TSocket; stdcall; старый код winsock2.pas: function WSAAccept( s : TSocket; addr : TSockAddr; addrlen : PInteger; lpfnCondition : LPCONDITIONPROC; dwCallbackData : DWORD ): TSocket; stdcall; кстате, скачивал winsock2.pas с различных мест раз пять, везде был одинаковый неправильный вариант... Просьба, выложите пожалуйста правильный вариант этого модуля, может это у меня не одна ошибка... спасибо |
|
Сообщ.
#2
,
|
|
|
|
Вопрос в догонку:
если я отклоняю запрос на подключение CF_Reject, то событие FD_ACCEPT на сервере возникает еще два раза, через каждые пол секунды и только после этого на клиенте возникает событие FD_CONNECT с ошибкой WSAECONNREFUSED. Почему три раза и как этим можно управлять? Спасибо |
|
Сообщ.
#3
,
|
|
|
|
Цитата _zsv_ @ если я отклоняю запрос на подключение CF_Reject, то событие FD_ACCEPT на сервере возникает еще два раза, через каждые пол секунды и только после этого на клиенте возникает событие FD_CONNECT с ошибкой WSAECONNREFUSED. Как вы отлавливаете FD_ACCEPT? |
|
Сообщ.
#4
,
|
|
|
|
Цитата Oleg2004 @ Как вы отлавливаете FD_ACCEPT? эвентом Evt:=WSAWaitForMultipleEvents(1,@Events, false, TimeOut, False); case Evt of WAIT_OBJECT_0: begin WSAEnumNetworkEvents(FSocket, Events[0], @NetworkEvents); if (NetworkEvents.lNetworkEvents and FD_ACCEPT>0) then begin ErrorCode:=NetworkEvents.iErrorCode[FD_ACCEPT_Bit]; ....вот сюда три раза и входит |
|
Сообщ.
#5
,
|
|
|
|
Я не совсем это имел в виду.
На каком сокете (слушающем, клиентском)вы отслеживаете появление события FD_ACCEPT |
|
Сообщ.
#6
,
|
|
|
|
В XE2 в прототипе PSockAddr
|
|
Сообщ.
#7
,
|
|
|
|
Цитата Oleg2004 @ На каком сокете слушающем Добавлено Цитата Fr0sT @ В XE2 в прототипе PSockAddr недопонял, а что там? |
|
Сообщ.
#8
,
|
|
|
|
Цитата _zsv_ @ недопонял, а что там? В юните этой версии среды декларация функции - именно та, как должна быть. Это к вопросу о "самой правильной версии юнита" |
|
Сообщ.
#9
,
|
|
|
|
_zsv_
Цитата На основе анализа возврата WSAAccept() принимает решение о дальнейшей обработке, или о создании группы сокетов, или подключает сокет к уже существующей группе. Например, надо отказаться от обслуживания запроса. Функция анализа возвращает CF_REJECT и WSAAccept() в свою очередь возвращает INVALID_SOCKET с кодом ошибки WSAECONNREFUSED. Режим вызова процедуры, адресованной lpfnCondition, осуществляется установкой опции прослушивающего сокета SO_CONDITIONAL_ACCEPT (тип - BOOL). У вас эта опция установлена? ![]() ![]() Evt:=WSAWaitForMultipleEvents(1,@Events, false, TimeOut, False); case Evt of WAIT_OBJECT_0: begin WSAEnumNetworkEvents(FSocket, Events[0], @NetworkEvents); if (NetworkEvents.lNetworkEvents and FD_ACCEPT>0) then begin ErrorCode:=NetworkEvents.iErrorCode[FD_ACCEPT_Bit]; ....вот сюда три раза и входит Вопрос - как можно войти в линейный код три раза??? И куда - сюда? Приведите код до вызова WSAAccept() |
|
Сообщ.
#10
,
|
|
|
|
Цитата Oleg2004 @ У вас эта опция установлена? да, при создании потока прослушки ... Cond:=true; SetSockOpt(FSocket, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, @Cond, SizeOf(Cond)); ... вот код выполнения потока прослушки (убиваю лишнее, поэтому может где-нить остаться хомуты) procedure TZsNPCMembersThread.Execute; var ... begin Events[0] := FWSAEvent; ResetEvent(Events[0]); while Not Terminated do begin TimeOut:=WSA_INFINITE; Evt:=WSAWaitForMultipleEvents(1,@Events, false, TimeOut, False); case Evt of WAIT_OBJECT_0 + 1: begin WSAEnumNetworkEvents(FSocket, Events[0], @NetworkEvents); if (NetworkEvents.lNetworkEvents and FD_ACCEPT>0) then begin ErrorCode:=NetworkEvents.iErrorCode[FD_ACCEPT_Bit]; ...сюда заходит три раза с периодичностью 0.5 сек при одной попытке подключения клиента ...делаю вывод что Events[0] выставляется три раза ...в клиентской программе connect выполняется точно один раз if ErrorCode=0 then begin i:=SizeOf(FNPC.FSockAddrIn); tmpSocket:=WSAAccept(FSocket, @FSockAddrIn, @i, CallBackAccept, 0); end; end; end; WAIT_FAILED:; WAIT_TIMEOUT:; end; end; CloseSocket(FSocket); end; Добавлено в CallBackAccept просто Result:=CF_REJECT; |
|
Сообщ.
#11
,
|
|
|
|
Поставьте пожалуйсте тег CODE и определите границы цикла
while Not Terminated do begin ..... ..... end По логике - зайти в цикл while Not Terminated do begin трижды можно только при неверной работе с Not Terminated Скорее всего там и надо искать.... |
|
Сообщ.
#12
,
|
|
|
|
Всем спасибо, проблема разрешилась сама собой. Код постоянно меняется, так и не понял на каком этапе проблема исчезла...Кривые руки однако...
|