[fpc-pascal] fphttclient, no way to specify a connect timeout
Dimitrios Chr. Ioannidis
d.ioannidis at nephelae.eu
Sat Feb 24 15:38:11 CET 2018
Hi,
Στις 24/2/2018 2:00 μμ, ο Luca Olivetti έγραψε:
< snip >
>> OK. I got it. Point taken.
>
> I don't think you did <snip>
No I really did ;).
>
> The only reliable way to enforce a connect timeout is to try to
> connect in non-blocking mode.
Something like this ( sorry again in ssockects.pp ) for windows only,
very draft code proof of concept which it works ( windows 10 here ) :
Procedure TInetSocket.Connect;
Var
A : THostAddr;
addr: TInetSockAddr;
Res : Integer;
nb: DWord;
fds: WinSock2.TFDSet;
opt: LongInt = 1;
len: LongInt;
tv : timeval;
rslt: longint;
begin
A := StrToHostAddr(FHost);
if A.s_bytes[1] = 0 then
With THostResolver.Create(Nil) do
try
If Not NameLookup(FHost) then
raise ESocketError.Create(seHostNotFound, [FHost]);
A:=HostAddress;
finally
free;
end;
addr.sin_family := AF_INET;
addr.sin_port := ShortHostToNet(FPort);
addr.sin_addr.s_addr := HostToNet(a.s_addr);
tv.tv_sec := IOTIMEOUT div 1000;
tv.tv_usec := 0;
WinSock2.FD_ZERO(fds);
WinSock2.FD_SET(Handle, fds);
nb := 1;
rslt := WinSock2.ioctlsocket(HANDLE, WinSock2.FIONBIO, @nb);
writeln(IntToStr(rslt));
{$ifdef unix}
Res := ESysEINTR;
while (Res = ESysEINTR) do
{$endif}
Res := fpConnect(Handle, @addr, sizeof(addr));
if WinSock2.select(Handle, nil, @fds, nil, @tv) > 0 then
begin
len := SizeOf(opt);
if WinSock2.FD_ISSET(Handle, FDS) then
fpgetsockopt(Handle, SOL_SOCKET, SO_ERROR, @OPT, @LEN);
Res := Opt;
end;
nb := 0;
WinSock2.ioctlsocket(HANDLE, WinSock2.FIONBIO, @nb);
If Not (Res<0) then
if not FHandler.Connect then
begin
Res:=-1;
CloseSocket(Handle);
end;
If (Res<0) then
Raise ESocketError.Create(seConnectFailed, [Format('%s:%d',[FHost,
FPort])]);
end;
regards,
--
Dimitrios Chr. Ioannidis
More information about the fpc-pascal
mailing list