Привет Всем! Проблема: Пишу сервер, с асинхронными сокетами. Где аботает: ================================================ 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 LocalPortWORD ;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 1785783615__XServer Final.rar
Всем пасиба! 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 ================================================ Тему считать закрытой.