Сел писать код, который конектится к smtp по заданному его ip, а в случае напал на ip c закрытым 25 портом хочу быстро отпасть. Для этого использовал функцию select(), заполнил структуры ... вот код ... Вход - стока с ip - адресом --> _strIP Выход - (0) если сервер ответил строкой "220 ..." и (-1) если сервер не вернул строку с "220 ... ". Код (Text): invoke WSAStartup,101h,offset wsadata invoke socket,AF_INET,SOCK_STREAM,0 .if eax != INVALID_SOCKET mov sock,eax mov s_addr.sin_family,AF_INET invoke htons,25 mov s_addr.sin_port,ax invoke inet_addr,[_strIP] mov s_addr.sin_addr,eax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; xor edx, edx mov time_out.tv_sec, 0 mov time_out.tv_usec, 500 mov dword ptr [fds.fd_count], 1 push sock pop fds.fd_array invoke select, 0, ADDR fds, ADDR fds, 0, ADDR time_out ; Ждем (500 ms) .if eax != INVALID_SOCKET invoke connect,sock,addr s_addr,sizeof s_addr .if eax != INVALID_SOCKET invoke recvfrom, sock, ADDR r_buf, 512, 0, addr s_addr, sizeof s_addr cmp dword ptr [r_buf],' 022' jz ___quit0 .endif .endif .endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ___quit1: invoke closesocket,sock invoke WSACleanup xor eax,eax mov eax,-1 ret ___quit0: invoke closesocket,sock invoke WSACleanup xor eax,eax ret Если _strIP - адрес реального smtp - сервера, то результат приходит быстро. Если _strIP - адрес не smtp - сервер, то результат приходится ждать долго. Но я же в задержке задал конкретный (короткий) интервал? Мне кажется что я неправильно применяю эту функцию select(). Поясните, пожалуйста, что делать чтобы не все-таки 500ms ждать результат выполнения connect().
В твоем случае select не подходит. Там есть только один связанный с этим событием набор - writefds - но только при неблокирующем вызове соединения. Поэтому используй неблокирующий режим работы сокетов. Сокет можно привести в неблокирующий режим так - Код (Text): .data? Num dd 1 ... invoke ioctlsocket,socket,FIOBIO,offset Num
Mental_Mirror тоесть выбросить этот select() ... и сделать следующее ... Код (Text): .data? Num dd 1 . . . invoke WSAStartup,101h,offset wsadata invoke socket,AF_INET,SOCK_STREAM,0 .if eax != INVALID_SOCKET mov sock,eax mov s_addr.sin_family,AF_INET invoke htons,25 mov s_addr.sin_port,ax invoke inet_addr,[_strIP] mov s_addr.sin_addr,eax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; invoke ioctlsocket,socket,FIOBIO,offset Num ; <------------!!! .if eax != INVALID_SOCKET invoke connect,sock,addr s_addr,sizeof s_addr .if eax != INVALID_SOCKET invoke recvfrom, sock, ADDR r_buf, 512, 0, addr s_addr, sizeof s_addr cmp dword ptr [r_buf],' 022' jz ___quit0 .endif .endif .endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ___quit1: invoke closesocket,sock invoke WSACleanup xor eax,eax mov eax,-1 ret ___quit0: invoke closesocket,sock invoke WSACleanup xor eax,eax ret
_animaTOR_ Теперь просто connect сразу вернет управление со статусом - "в процессе". Следующие вызовы connect могут вернуть успех, либо опять же "в процессе". Теперь select просто будет работать на событии об успешном соединении и connect не будет тормозить, т.к. он сразу будет возвращаться. Т.о. select просто не работает на блокирующем сокете. Ну это можно почитать в SDK.