Проблема с асинхронным разрывом связи WSA.

Тема в разделе "WASM.NETWORKS", создана пользователем xenomorph, 15 май 2005.

Статус темы:
Закрыта.
  1. xenomorph

    xenomorph New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    16
    Адрес:
    Это не важно, на сегодня у мен
    Привет Всем!



    Проблема:



    Пишу сервер, с асинхронными сокетами.



    Где аботает:

    ================================================

    listen on port 1000 - OK

    closesocket - OK (уходит с нетстата) - т.е сокет закрываеться.

    ...

    опять повторяем:

    listen on port 1000 - OK

    closesocket - OK (уходит с нетстата) - т.е сокет закрываеться.

    всё работает ...

    ================================================



    НО! если соедениться с этим сокетом внешним клиентом,

    а затем порвать соединение ...



    Приходит FD_CLOSE, я его обрабатываю закрытием сокета:

    invoke closesocket, hSocket /// но это ничего не даёт!



    т.е. abottion а не graceful shutdown - сокет висит (!).

    его прибить нельзя 8(((. сlosesocket срабвтывает - ошибки нет ...

    но порт висит открытым ... и повторный bind - выдаёт ошибку 8(((.



    Если поменять порт, то listen запускаеться.

    Но "висящий" сокет красиво висит вплоть до ExitProcess 8(((.

    ================================================

    Люди помогите пожалуйста!

    --

    Заранее огромное спасибо!

    ================================================

    Код:

    ;............................................................

    ;Сообщения от сокета:

    ;............................................................

    .elseif uMsg == WM_SOCKET



    mov eax, lParam ;Saving the Parameter



    PrintDec wParam

    PrintDec lParam



    .if ax == FD_CONNECT ;если сообщение о состоявшемся подключении

    HIWORD lParam

    .if ax == NULL ;отсутcтвует ошибка

    mov Connected, 1

    PrintText "Connected!"

    .else ;ошибка

    mov Connected, 0

    PrintText "Connection Failure!"

    .endif

    .elseif ax == FD_CLOSE ;если сообщение о закрытии сокета

    HIWORD lParam

    .if ax==NULL ;отсутствует ошибка

    PrintText "Сокет закрыт"

    PrintText "Closing Socket Handle:"

    PrintDec hSocket

    invoke closesocket, hSocket

    mov Connected, 0

    mov hSocket, 0

    invoke NotifyC, 10, 0

    .else ;ошибка

    .if Connected==1

    .endif

    .endif

    .elseif ax == FD_ACCEPT

    PrintText "Incoming Connection ..."

    HIWORD lParam

    .if ax == NULL ; отсутствует ошибка

    invoke NotifyC, 9, 0 ;Информируем контроллер - Входящий запрос

    .else ; ошибка

    mov Connected, 0

    .endif

    .elseif ax == FD_READ

    PrintText "Incoming Data From Socket"

    invoke NotifyC, 11, 0 ;Информируем контроллер - Данные приехали на сокет



    .elseif ax == FD_WRITE

    PrintText "Socket Is Ready For Writing"

    .endif

    .else ; если мы не обрабатываем сообщение, надо его вернуть со всеми параметрами

    invoke DefWindowProc, hWnd, uMsg, wParam, lParam

    ret

    .endif

    xor eax,eax

    ret



    WndProc endp



    ;--------------------------------------------------------------------- -----------------------

    ;Listen On Port:

    ;--------------------------------------------------------------------- -----------------------

    ListenOnPort proc LocalPort:lol: WORD ;Listen on Port

    ;нужно откpыть сокет (в дальнейшем он будет использоваться на прием )



    invoke socket, AF_INET, \ ; Address family (в веp 1.1 доступно только семейство AF_INET)

    SOCK_STREAM,\ ; задает тип сокета (STREAM или DATAGRAM)

    0 ; тип протокола (не устанавливать никакого пpотокола: 0)

    .if eax != INVALID_SOCKET ; если нет ошибки

    mov hSocket, eax ; запомнить хендл

    PrintText "LSocket Handle:"

    PrintDec hSocket

    .else

    PrintText "Fatal Error 1"

    .endif

    ; WSAAsyncSelect function requests Windows message-based notification of network events for a socket

    ; функция указывает Windows посылать сообщения заданному окну от определенного сокета

    invoke WSAAsyncSelect, hSocket, MWH, WM_SOCKET, FD_ACCEPT+FD_READ+FD_CLOSE+FD_CONNECT

    .if eax == INVALID_SOCKET



    .endif

    invoke htons, LocalPort ; преобразовать номер порта в сетевой порядок байт

    mov sin.sin_port, ax

    mov sin.sin_family, AF_INET

    mov sin.sin_addr, INADDR_ANY



    invoke bind, hSocket, addr sin, sizeof sin ; ассоциировать локальный адрес (представленный в структуре sin) с сокетом

    PrintError

    ; the Windows Sockets listen function establishes a socket to listen for an incoming connection

    ; устанавливает сокет в состояние, в котором он слушает порт на предмет входящих соединений

    invoke listen, hSocket, 5

    .if eax == SOCKET_ERROR

    PrintText "Fatal Error 3"

    .endif



    PrintText "Socket Listening on Port:"

    PrintDec LocalPort

    ret



    ListenOnPort endp

    [​IMG] 1785783615__XServer Final.rar
     
  2. xenomorph

    xenomorph New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    16
    Адрес:
    Это не важно, на сегодня у мен
    Всем пасиба! 8)

    Расчехлился сам 8)))).



    Расщепление сокета на 2 части делать так:



    Вот ПРАВИЛЬНЫЙ код:

    ;--------------------------------------------------------------------- -----------------------

    ;Accepting Incoming Call

    ;--------------------------------------------------------------------- -----------------------

    AcceptCall proc

    mov Connected, 1

    PrintText "Accepting Incoming Call!"

    mov ebx, hSocket

    mov hSocket2, ebx

    invoke accept, hSocket, addr RemoteHostIP, 0

    PrintText "Socket Handle Accepted COnnection:"

    PrintDec hSocket ; нужно вызвать специальную ф-ию, чтобы разрешить входящее соединение

    mov hSocket, eax ; сохранить дескриптор сокета

    .if eax == INVALID_SOCKET

    PrintText "Acception Error:"

    PrintError

    .endif

    PrintText "Connection From:"

    PrintString RemoteHostIP

    AcceptCall endp

    ===============================================

    + Правильная процедура закрытия сокетов:

    ===============================================

    ;--------------------------------------------------------------------- -----------------------

    ;ResetSockets

    ;--------------------------------------------------------------------- -----------------------

    ResetSockets proc



    PrintText "Invoking Sockets Reset:"



    invoke WSAAsyncSelect, hSocket, MWH, 0, 0

    invoke closesocket, hSocket



    invoke WSAAsyncSelect, hSocket2, MWH, 0, 0

    invoke closesocket, hSocket2



    ret



    ResetSockets endp

    ================================================

    Тему считать закрытой.
     
Статус темы:
Закрыта.