Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > RecvFrom возвращает WSAEWOULDBLOCK


Автор: Lexicss 26.9.2008, 14:11
Работаю с протоколом UDP/IP 
Программа обрабатывает присланные ей датаграммы.
Вот часть кода :
Код

  repeat
    boError := False;
    WaitRes := MsgWaitForMultipleObjects(CountEvent, arrThrEvents, False, 300, QS_POSTMESSAGE) - WAIT_OBJECT_0;
    if WaitRes > 0
    then begin
      if WaitRes < CountEvent
      then begin
        SockAddrLen := sizeOf(TSockAddrIn);
        WSAResetEvent(arrThrEvent[WaitRes]);

        Received := RecvFrom(sock,recvbuff,sizeOf(recvbuff),0,SockAddrFrom,SockAddrLen);
        boError := (Received = SOCKET_ERROR);
        ......................
   until WaitRes = 0;


Когда программа запускается, а в во входном буффере данных нет - всё ок. 
Когда приходят  датаграммы, взводится событие arrThrEvent[1], RecvFrom возвращает число байт в датаграмме - всё ок, однако когда датаграммы заканчиваются - то событие всё равно взводится.
Срабатывает функция - RecvFrom с ошибкой WSAGetLastError = WSAEWOULDBLOCK. И всё цикл пошёл бесконечный, как будто я событие не сбрасываю. 

Прочитал в msdn, что типа это значит сокет в неблокирующем риежими и всё ок. Ну перевожу я его в блокирующий режим. Как я понял это делается так:
Код

arg := 0;
IOCtlSocket(sock, FIONBIO, arg)

Всё тоже самое. Проблема зацикливания остаётся, и грузит проц под 100%. Ничего не помогает. 

Пришлось сделать  так чтобы хоть нагрузку снять:
Код

  repeat
    boError := False;
    WaitRes := MsgWaitForMultipleObjects(CountEvent, arrThrEvents, False, 300, QS_POSTMESSAGE) - WAIT_OBJECT_0;
    if WaitRes > 0
    then begin
      if WaitRes < CountEvent
      then begin
        SockAddrLen := sizeOf(TSockAddrIn);
        WSAResetEvent(arrThrEvent[WaitRes]);
        arg := 0;
        IOCtlSocket(sock,FIONRead,arg)
        if arg = 0
        then begin
          sleep(500);
          continue;
        end;
        Received := RecvFrom(sock,recvbuff,sizeOf(recvbuff),0,SockAddrFrom,SockAddrLen);
        boError := (Received = SOCKET_ERROR);
        ......................
   until WaitRes = 0;


Но всё же хотел обратиться за помощью, можно ли как-то здесь придумть красиво чтобы по прибытию датаграмм событие не взаодилось до прибытия следующиХ?

Событие привязал так : WSAEventSelect(sock,arrThrEvent[1],FD_READ)

Автор: Lexicss 26.9.2008, 15:09
CountEvent = 2;

Автор: Lexicss 26.9.2008, 16:08
Нашёл в чём ошибка. В WSAResetEvent  указал элемент не того массива, но похожий на названием на тот что в MsgWait...
Блин, а немало времени убил на поиски...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)