помогите с сокетами на событиях

Тема в разделе "WASM.NETWORKS", создана пользователем h0kum, 28 апр 2007.

  1. h0kum

    h0kum New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2003
    Сообщения:
    47
    Добрый день.
    пишу службу, в неё создается поток, который обрабатывает, события:
    Код (Text):
    1. SocketThread Proc
    2. LOCAL  Event : dword
    3.     .while hStopEvent
    4.         lea eax,[NewEvent]
    5.         invoke WSAWaitForMultipleEvents, EventTotal, addr EventArray, TRUE,WSA_INFINITE, FALSE
    6.         mov Event, eax
    7.         .if  eax == INVALID_SOCKET
    8.             .continue
    9.         .endif
    10. ;       invoke WSAResetEvent,EventArray[eax*4]
    11.         mov ebx, Event
    12.         mov eax,ebx  
    13.         mov esi, SocketArray[ebx*4]    
    14.         .if eax==WSA_WAIT_FAILED
    15.             .continue
    16.         .elseif eax == 0
    17.             invoke WSAEnumNetworkEvents,Listen,EventArray[ebx*4],addr NetworkEvents
    18.             .if eax == INVALID_SOCKET                
    19.                 .continue
    20.             .endif      
    21.             lea  edx, NetworkEvents
    22.             mov  eax, (WSANETWORKEVENTS ptr [edx]).lNetworkEvents
    23.             ;----------------------------------------------------------
    24.             .if  eax & FD_ACCEPT    ; = 8
    25.                 lea  ecx, (WSANETWORKEVENTS ptr [edx]).iErrorCode
    26.                 add  ecx, FD_ACCEPT_BIT
    27.                 .if  dword ptr [ecx] != 0                      
    28.                     ;.break
    29.                     .continue
    30.                 .endif
    31.                 invoke accept, (SOCKET_INFORMATION ptr [esi]).Socket, 0, 0
    32.                 mov Accept, eax
    33.                 .if eax== INVALID_SOCKET                          
    34.                     .continue
    35.                 .endif
    36.                 .if EventTotal > WSA_MAXIMUM_WAIT_EVENTS ;=64
    37.                     invoke closesocket, Accept
    38.                     .continue
    39.                 .endif
    40.                 invoke CreateSocketInformation, Accept                  
    41.                 mov    ecx, EventTotal    
    42.                 dec    ecx
    43.                 mov    edx, EventArray[ecx*4]
    44.                 invoke WSAEventSelect, Accept, edx, FD_READ or FD_CLOSE ;FD_WRITE or  
    45.                 .if eax == SOCKET_ERROR                      
    46.                     .continue
    47.                 .endif              
    48.             .elseif eax & FD_READ   ; = 1
    49.                 .if (NetworkEvents.iErrorCode[FD_READ_BIT] != 0)                  
    50.                     .continue
    51.                 .endif                                        
    52.                 mov ebx, Event          
    53.                 mov esi, SocketArray[ebx*4]                  
    54.                 .if (dword ptr (SOCKET_INFORMATION ptr [esi]).BytesRECV == 0)                                    
    55.                     lea edi, (SOCKET_INFORMATION ptr [esi]).DataBuf
    56.                     mov (WSABUF ptr [edi]).buf,esi            
    57.                     mov (WSABUF ptr [edi]).len,4096
    58.                     mov Flags, 0
    59.                     invoke WSARecv, (SOCKET_INFORMATION ptr [esi]).Socket, edi, 1, addr RecvBytes, addr Flags, NULL, NULL
    60.                     .if (eax == -1)
    61.                         invoke WSAGetLastError
    62.                         .if (eax!= WSAEWOULDBLOCK)                                  
    63.                             invoke FreeSocketInformation, Event
    64.                             .continue
    65.                         .endif
    66.                     .else            
    67.                         mov  eax, RecvBytes
    68.                         mov  (SOCKET_INFORMATION ptr [esi]).BytesRECV,  eax
    69.                     .endif                              
    70.                 .endif          
    71.                 mov ebx, Event                  
    72.                 mov esi, SocketArray[ebx*4]  
    73.                 lea edi, (SOCKET_INFORMATION ptr [esi]).DataBuf
    74.                 mov (WSABUF ptr [edi]).buf, esi                    
    75.                 mov (WSABUF ptr [edi]).len, ecx
    76.                 mov (SOCKET_INFORMATION ptr [esi]).BytesRECV, 0                                                                                                      
    77.                 invoke SendData, Event
    78.                 mov eax,Event
    79.                 invoke WSAResetEvent,EventArray[eax*4]
    80.             .elseif eax & FD_CLOSE  ; = 20      
    81.                 .if (NetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0)                      
    82.                     .continue
    83.                 .endif          
    84.                 invoke FreeSocketInformation, Event
    85.                 mov eax,Event
    86.                 invoke WSAResetEvent,EventArray[eax*4]
    87.             .endif    
    88.         .endif
    89.     .endw
    90.     ret
    91. SocketThread endp
    на РНР для тестирования написал, такой код:
    Код (Text):
    1. <?php
    2.     $package = "test";
    3.     $soc = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
    4.     if($soc===FALSE)
    5.     {
    6.         echo "Don't create socket";
    7.         exit();
    8.     }
    9.     $res = socket_connect($soc,"localhost",4005);
    10.     if($res===FALSE)
    11.     {
    12.         echo "Don't connect to socket";
    13.         exit();
    14.     }
    15.     socket_write($soc, $package, strlen($package));
    16. ?>
    в отладчике смотрю, на:
    Код (Text):
    1. invoke WSAEnumNetworkEvents,Listen,EventArray[ebx*4],addr NetworkEvents
    2. lea  edx, NetworkEvents
    3. mov  eax, (WSANETWORKEVENTS ptr [edx]).lNetworkEvents
    первый раз ЕАХ = FD_ACCEPT
    второй раз ЕАХ = 0

    хотя после:
    socket_write($soc, $package, strlen($package));

    должно быть событие FD_READ
    ни чего не понимаю от куда 0 ?!

    даже если убрать в РНР скрипте:
    socket_write($soc, $package, strlen($package));
    всё равно есть 0, но нет события на чтение.

    Может мне кто нибудь обяснить в чем проблема?
    Спасибо
     
  2. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    не eax == INVALID_SOCKET , а eax == WSA_WAIT_FAILED
    хотя это в принципе неважно..

    ps: WSAEnumNetworkEvents всегда вызывается для Listen, а событие FD_READ происходит для Accept
     
  3. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    >invoke WSAEnumNetworkEvents,Listen,EventArray[ebx*4],addr NetworkEvents

    нужно очищать структуру NetworkEvents
     
  4. h0kum

    h0kum New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2003
    Сообщения:
    47
    Доброго времени суток.
    В принципе я нашел в чем причина, этот кусок кода я нашел тут на форуме, ошибка была в
    invoke WSAEnumNetworkEvents,Listen,EventArray[ebx*4],addr NetworkEvents
    надо было написать:
    invoke WSAEnumNetworkEvents,(SOCKET_INFORMATION ptr [esi]).Socket,EventArray[ebx*4],addr NetworkEvents

    0-к он все равно приходил, но после него были и FD_READ, FD_CLOSE