Opened 10 years ago
Closed 4 years ago
#2835 closed Feature Request (Completed)
Change the TCP*() funktions to optional use non blocking ports.
Reported by: | rthilo | Owned by: | |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | Severity: | None | |
Keywords: | network non blocking ports timeout | Cc: |
Description
Hello.
The timeouts of the TCP*() functions doesn't seem to have effect. Some kind fellow from a different forum explained to me, that's most propably due to the use of *BLOCKING* ports by these functions. He wrote this EXE for me, I use it with fileinstall() in case I need to check lot's of IP:PORT status.
Suggestion: Modify the network functions of Autoit, so that they (at least optional) also use non blocking ports, so that short timeouts can be reality.
the ChkPort.PAS example code that fellow wrote for me is this:
[code]
program chkPort;
Input: chkport-ip <ip address> <port> [timeout]
Output: Text message + Errorlevel
0 if we connect,
1 if we timeout,
2 if we get a socket failure,
3 for an invalid address.
uses sockets,inetaux,strutils,winsock2,sysutils;
var
ConSock : LongInt;
sAddr : TInetSockAddr;
timeout : dword;
result : boolean;
procedure setnonblockingsocket( s : integer );
var
nb : dword;
begin
nb := 1; 1 = nonblocking, 0 = blocking
winsock2.ioctlsocket( s , FIONBIO , @nb );
end;
function is_writable_socket( sck : integer; timeout : dword ) : boolean;
var
fds : tfdset;
tv : timeval;
result : boolean;
begin
fd_zero( fds );
fd_set( sck , fds );
tv.tv_sec := timeout div 1000;
tv.tv_usec := timeout mod 1000;
select (socket+1 , read , write , except , timeout) - wait
"timeout" to see if data can be written to "socket" without
blocking
result := select( sck + 1 , nil , @fds , nil , @tv ) > 0;
is_writable_socket := result;
end;
begin
create a socket, die if we fail
ConSock := Socket(af_inet, sock_stream, 0);
if ConSock = -1 then begin
writeln('Could not open socket: ');
halt(2);
end
else begin
make it non-blocking
SetNonBlockingSocket(ConSock);
if timeout defined use it, otherwise default to 2 secs
If paramcount >= 3 then Timeout := numb2dec(paramstr(3),10)
else timeout := 2000;
fill in the socket info - protocol, address, port
with sAddr do begin
Family := af_inet;
Port := htons(numb2dec(paramstr(2),10));
Addr := StrToAddr(paramstr(1));
end;
die if we can't turn the address into something useable
If saddr.Addr = 0 then begin
writeln('Could not resolve ',paramstr(1));
halt(3);
end;
otherwise try to connect
Result := (fpConnect(ConSock, @sAddr, sizeof(sAddr)) = 0);
and see if it become writeable in the time allowed
result := result or is_writable_socket(consock, timeout);
close the socket
Shutdown(ConSock, 2);
and report results
If result then writeln('Port listening')
else begin
Writeln('Port not listening');
halt(1);
end;
end;
end.
code
the compiled EXE is available from my dropbox here:
https://dl.dropboxusercontent.com/u/19989673/ChkPort-IP/chkport.exe
Hoping to have explained it correctly, thanks for Autoit!
Regards, Rudi.
Attachments (0)
Change History (2)
comment:1 Changed 10 years ago by TicketCleanup
- Version 3.3.12.0 deleted
comment:2 Changed 4 years ago by Jpm
- Resolution set to Completed
- Status changed from new to closed
Sorry to be so late on the subject.
I recheck the AutoIt code and find out that TCPConnect() is doing exactly except for the Shutdown(ConSock, 2);
in fact this possibility has been added in a new TCPShutdownSocket(2)
perhaps in your case the complete closing of the socket is better with the new extension of the TCPCloseSocket(sock, 2)
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Automatic ticket cleanup.