Добрый день имеется вот такой код. Проверка на открытый порт происходит успешно, а когда надо получить ответ то WinSock возвращает ошибку 10035. Вообще задача получить не всю страницу, а достаточно только Headers. В первую очередь важна скорость. Code: function TCheckerThread.CheckPort: Boolean; var s, opt, BytesRead: Integer; FSocket: TSOCKET; addr: TSockAddr; hEvent: THandle; fset: TFDset; tv: TTimeval; Get, Response: string; begin Result := false; addr.sin_family := AF_INET; addr.sin_addr.s_addr := INADDR_ANY; addr.sin_addr := IP; hEvent := WSACreateEvent(); FSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_IP); try if (FSocket = INVALID_SOCKET) then begin Result := True; Exit; end; WSAEventSelect(FSocket, hEvent, FD_WRITE + FD_CONNECT); addr.sin_port := Port; connect(FSocket, @addr, sizeof(addr)); if (WSAGetLastError() = WSAEINPROGRESS) then begin Result := true; Exit; end; FD_Zero(fset); FD_SET(FSocket, fset); tv.tv_sec := 1; tv.tv_usec := 0; s := select(1, nil, @fset, nil, @tv); if (not FD_ISSET(FSocket, fset)) then begin Result := true; Exit; end; s := Sizeof(opt); opt := 1; getsockopt(FSocket, SOL_SOCKET, SO_ERROR, @opt, s); if (opt <> 0) then begin Result := true; Exit; end; ToDebug('Port opened'); Get := Format('GET / HTTP/1.1'#13#10 + 'Host: %s'#13#10 + 'User-Agent: %s'#13#10 + 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'#13#10 + 'Accept-Language: en-US,en;q=0.5'#13#10 + 'Accept-Encoding: gzip, deflate'#13#10 + 'Connection: keep-alive'#13#10 + #13#10, [IpStr, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0']); if Send(FSocket, PChar(Get)^, Length(Get), 0) = SOCKET_ERROR then begin Result := True; Exit; end; SetLength(Response, 65536); BytesRead := Recv(FSocket, PChar(Response)^, 65536, 0); case BytesRead of -1: ToDebug('Recv error: ' + IntToStr(WSAGetLastError)); 0: ToDebug('Connection closed by peer'); else Response[BytesRead] := #0; ToDebug('Response: ' + Response); end; finally if closesocket(FSocket) <> 0 then ToDebug('Error closed socket'); WSACloseEvent(hEvent); end; end;
10035 WSAEWOULDBLOCK Resource temporarily unavailable (Ресурс временно недоступен). Эта ошибка возвращается операциями с неблокирующими сокетами, которые не могут быть немедленно завершены. Это не фатальная ошибка. Обычно WSAEWOULDBLOCK возвращается как результат вызова connect() на неблокирующем сокете SOCK_STREAM, поскольку для установления соединения требуется некоторое время. По пробуй обрати внимание на свой код в Socket tv.tv_sec := 1; и tv.tv_usec := 0; пробуй изменить возможно не успевает ответить, за такой короткий промежуток и не дожидается завершения таймаута.
Ну это не вариант т.к. тогда очень долго проверяется открыт порт или нет. Сейчас сделала вот так. Но считаю это не правильный вариант. Может есть какой-то лучше способ для этого? К примеру так же поставить евент до ожидания когда можно получить ответ. Code: repeat BytesRead := Recv(FSocket, PChar(Response)^, 65536, 0); case BytesRead of -1: Sleep(500); //ToDebug('Õîñò ' + IpStr + ' Recv error: ' + IntToStr(WSAGetLastError)); 0: ToDebug('Connection closed by peer'); else Response[BytesRead] := #0; ToDebug('Õîñò ' + IpStr + ' îòâå÷àåò ' + Response); end; until WSAGetLastError <> WSAEWOULDBLOCK;