На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

Не приветствуется поднятие старых тем. Если ваш вопрос перекликается со старой темой, то для вопроса лучше создать новую тему, а старую указать в первом сообщении с описанием взаимосвязи.

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Проблема с WSAAccept
    День добрый , подскажите, что не так делаю...
    При выполнении DoAccept (разрешение на подключение клиента) даже не входит в Callback-функцию, а после выполнения DoAccept вообще вываливается "аккесс виол.."
    Сокет неблокирующий, DoAccept пытаюсь выполнить по сигналу эвента FD_ACCEPT, все (создание сокета,прослушивание и ожидание сигналов) делается в отдельном потоке, ф-ю CallBackAccept больше нигде не определял..
    ExpandedWrap disabled
      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 с различных мест раз пять, везде был одинаковый неправильный вариант... Просьба, выложите пожалуйста правильный вариант этого модуля, может это у меня не одна ошибка...
    спасибо
      Вопрос в догонку:
      если я отклоняю запрос на подключение CF_Reject, то событие FD_ACCEPT на сервере возникает еще два раза, через каждые пол секунды и только после этого на клиенте возникает событие FD_CONNECT с ошибкой WSAECONNREFUSED. Почему три раза и как этим можно управлять?
      Спасибо
        Цитата _zsv_ @
        если я отклоняю запрос на подключение CF_Reject, то событие FD_ACCEPT на сервере возникает еще два раза, через каждые пол секунды и только после этого на клиенте возникает событие FD_CONNECT с ошибкой WSAECONNREFUSED.

        Как вы отлавливаете FD_ACCEPT?
          Цитата 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];
          ....вот сюда три раза и входит
            Я не совсем это имел в виду.
            На каком сокете (слушающем, клиентском)вы отслеживаете появление события FD_ACCEPT
              В XE2 в прототипе PSockAddr
                Цитата Oleg2004 @
                На каком сокете

                слушающем

                Добавлено
                Цитата Fr0sT @
                В XE2 в прототипе PSockAddr

                недопонял, а что там?
                  Цитата _zsv_ @
                  недопонял, а что там?

                  В юните этой версии среды декларация функции - именно та, как должна быть. Это к вопросу о "самой правильной версии юнита"
                    _zsv_
                    Цитата
                    На основе анализа возврата WSAAccept() принимает решение о дальнейшей обработке, или о создании группы сокетов, или подключает сокет к уже существующей группе. Например, надо отказаться от обслуживания запроса. Функция анализа возвращает CF_REJECT и WSAAccept() в свою очередь возвращает INVALID_SOCKET с кодом ошибки WSAECONNREFUSED.
                    Режим вызова процедуры, адресованной lpfnCondition, осуществляется установкой опции прослушивающего сокета SO_CONDITIONAL_ACCEPT (тип - BOOL).

                    У вас эта опция установлена?

                    ExpandedWrap disabled
                      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()
                      Цитата 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;
                        Поставьте пожалуйсте тег CODE и определите границы цикла
                        while Not Terminated do
                        begin
                        .....
                        .....
                        end
                        По логике - зайти в цикл while Not Terminated do begin трижды можно только при неверной работе с Not Terminated
                        Скорее всего там и надо искать....
                        Сообщение отредактировано: Oleg2004 -
                          Всем спасибо, проблема разрешилась сама собой. Код постоянно меняется, так и не понял на каком этапе проблема исчезла...Кривые руки однако...
                          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0.0924 ]   [ 15 queries used ]   [ Generated: 24.10.26, 03:03 GMT ]