-
День добрый , подскажите, что не так делаю... При выполнении 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(FNPC.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 с различных мест раз пять, везде был одинаковый неправильный вариант... Просьба, выложите пожалуйста правильный вариант этого модуля, может это у меня не одна ошибка... спасибо
-
Вопрос в догонку: если я отклоняю запрос на подключение CF_Reject, то событие FD_ACCEPT на сервере возникает еще два раза, через каждые пол секунды и только после этого на клиенте возникает событие FD_CONNECT с ошибкой WSAECONNREFUSED. Почему три раза и как этим можно управлять? Спасибо
-
> Почему три раза
Видимо с ивентом ка-то криво работаешь ..
-
День добрый, Мастера.. Проблема трех эвентов так и осталась. Вот код потока, который слушает сокет
procedure TZsNPCMembers.Execute;
var Evt: LongWord;
e: TNPCErrorInfo;
Events: array[0..1] of THandle; NetworkEvents:TWSANetworkEvents;
i:integer;
tmpSocket: TSocket;
begin
Events[0] := FInternalEvent; Events[1] := FWSAEvent;
while Not Terminated do begin
Evt:=WSAWaitForMultipleEvents(2,@Events, false, WSA_INFINITE, False);
case Evt of
WAIT_OBJECT_0: ResetEvent(Events[0]);
WAIT_OBJECT_0 + 1: begin
WSAEnumNetworkEvents(FSocket, Events[1], @NetworkEvents);
if (FNPC.FAppType=npcatServer) And
(NetworkEvents.lNetworkEvents and FD_ACCEPT>0) then begin
i:=NetworkEvents.iErrorCode[FD_ACCEPT_Bit];
if i=0 then begin
i:=SizeOf(FSockAddrIn);
tmpSocket:=WSAAccept(FSocket, @FSockAddrIn, @i, CallBackAccept, DWord(FNPC));
WriteToFile('qqq.txt', inttostr(GetTickCount)+' Сервер. Запрос подключения1 '+IntToStr(WSAGetLastError));
end else begin
WriteToFile('qqq.txt', inttostr(GetTickCount)+' Сервер. Запрос подключения2 '+IntToStr(i));
end;
end;
if (FNPC.FAppType=npcatClient) And
(NetworkEvents.lNetworkEvents and FD_CONNECT>0) then begin
i:=NetworkEvents.iErrorCode[FD_CONNECT_Bit];
sleep(100);
WriteToFile('qqq.txt', inttostr(GetTickCount)+' Клиент. Подключение '+IntToStr(i));
end;
end;
WAIT_FAILED:; WAIT_TIMEOUT: end;
end;
end;
В этом коде конечно много чего осталось "за кадром", различные определения, типы и тд, но в целом алгоритм прослушки виден Могу выложить весь проект, но к сожалению форум не дает прикреплять файлы... Спасибо, надеюсь на помощь
-
-
Это не мой случай. у меня принимается именно три эвента FD_ACCEPT если я отказываю в акцепте, и только после этого на клиенте появляется результат. Все это происходит если в коде есть установка SetSockOpt(Socket, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, @Cond, SizeOf(Cond)); Если этой установки нет, то эвент устанавливается один, не зависимо от того принимаю я акцепт или нет, а клиент получает ответ сразу о подключении...
-
> три эвента FD_ACCEPT если я отказываю в акцепте
А если не отказываешь и сразу же акцептируешь ? И нет ли других взведенных флагов кроме FD_ACCEPT ?
-
если не отказываю - то больше FD_ACCEPT не появляется. Других взведенных флагов нет...
-
-
-
> han_malign (02.07.13 17:36) [10]
А нафига тогда в примере по моей ссылке стоит вызов WSAResetEvent() ? Типа "щоб було" на всякий пожарный случай, для пущей надежности - а ну как не сбросится сигнал ?
> record of network events is not cleared.
Ну это , как и я предполагаю, и есть причина "повторных сигналов" .. Но как тут можно умудриться передать null (или вообще там мусор ?) в кач-ве хендла ивента - не представляю.
А то что нехило было бы анализировать результат вызова WSAWaitForMultipleEvents() на предмет SOCKET_ERROR, хотя бы на этапе отладки - это да, солидарен.
-
> А нафига тогда в примере по моей ссылке стоит вызов WSAResetEvent()?
- потому что там overlapped WSARecv - WSAEnumNetworkEvents не используется...
> анализировать результат вызова WSAWaitForMultipleEvents()
- WSAEnumNetworkEvents... - результат Wait анализируется в case.
-
WSAEnumNetworkEvents возвращает 0 во всех трех случаях :((( а я так надеялся... Может выложить весь проект, там только форма и код подключения. Только не дает выкладывать из-за большого размера кода...
-
> zsv (01.06.13 11:42) [1] > старый код winsock2.pas: > function WSAAccept( s : TSocket; addr : TSockAddr; addrlen > : PInteger; lpfnCondition : LPCONDITIONPROC; dwCallbackData > : DWORD ): TSocket; stdcall; > > кстате, скачивал winsock2.pas с различных мест раз пять, > везде был одинаковый неправильный вариант... Просьба, выложите > пожалуйста правильный вариант этого модуля, может это у > меня не одна ошибка... > спасибо
Не знаю, откуда ты качал, но у меня function WSAAccept( const s : TSocket; addr : PSockAddr; addrlen : PInteger; lpfnCondition : LPCONDITIONPROC; const dwCallbackData : DWORD ): TSocket; stdcall; Специально скачал у себя с сайта и перепроверил. http://home.earthlink.net/~akonshin/delphi_ru.htmсам файл тут http://home.earthlink.net/~akonshin/files/ws2rev4a.zipНасколько я понял, большинство вариантов winsock2 в сети и в последних версиях Delphi - переделки из моего, там обычно даже мой копирайт присутствует. Вот, интересно, что в FPC 2.6.0 в файле мой копирайт есть, но баг присутствует... Наверно, в какой-то из предыдущих версий он был...
|