小弟我想检测一个IP的指定端口是否开放!

我想检测一个IP的指定端口是否开放!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
我想检测一个IP的指定端口是否开放,那么我连一下就知道了,
连上了就是开放,并且断开连接。连不上就是没有开放。

但是我又不想用控件,想直接用API,找到了如下代码,测试了没有效果,怎么连都是False;

function ScanTCPPort(ipstr : string; Port: DWORD): Boolean;
var
  option: DWORD;
  TcpSock: TSocket;
  InAddr: TSockAddrIn;
  IP : DWORD;
begin
  result := False;
  
  //convert IP string to ulong
  IP := ntohl(inet_addr(PChar(ipstr)));
  if IP = INADDR_NONE then //invalid IP address!
  exit;
  
  // Create/open a socket (stream, not datagram)
  TcpSock := socket(AF_INET, SOCK_STREAM, 0);
  if TcpSock = INVALID_SOCKET then //socket error
  exit;
   
  try
  // Set socket options
  option := 0;
  setsockopt(TcpSock, SOL_SOCKET, SO_KEEPALIVE, @option, sizeof(option));
  option := 1;
  setsockopt(TcpSock, SOL_SOCKET, SO_DONTLINGER, @option, sizeof(option));
   
  //if winsock 1.1, including the next sentence, otherwise, skip it.
  setsockopt(TcpSock, IPPROTO_TCP, TCP_NODELAY, @option, sizeof(option));
   
  //Initialize address structure
  ZeroMemory(@InAddr, sizeof(InAddr));
  InAddr.sin_family := AF_INET;
  InAddr.sin_addr.S_addr := ntohl(IP);
  InAddr.sin_port := htons(Port);
  //Try to connect
  Result := connect(TcpSock, InAddr, sizeof(InAddr)) = 0;
  finally
  //Close the socket
  closesocket(TcpSock);
  end;
end;






调用 if ScanTCPPort('110.75.161.108',16000) then ShowMessage('True') else ShowMessage('False');

我Telnet是连的上的...

谁帮忙改一下上面那个Function,或者给个更好的Function

要源码,测试可用马上结贴


我Delphi7

------解决方案--------------------
Delphi(Pascal) code
Function TryIPPort(Const IP : AnsiString; Port : integer) : Boolean;
var
  Sock : TSocket;
  SA   : TSockaddr;
  n , ul : integer;
  TV : TTimeVal;
  FDSet : TFDSet;
begin
  FillChar(SA , SizeOf(SA) , 0);
  SA.sin_family      := AF_INET;
  SA.sin_port        := htons(Port);
  SA.sin_addr.S_addr := inet_addr(Pointer(IP));
  Sock               := Socket(AF_INET , SOCK_STREAM , IPPROTO_IP);
  Result             := Sock<>invalid_socket;
  if Result then begin
    n := 3 * 1000;  //3秒超时
    ul := 1;
    if (SetSockopt(Sock , SOL_SOCKET , SO_SNDTIMEO , @n , SizeOf(n))<>SOCKET_ERROR) and
       (SetSockopt(Sock , SOL_SOCKET , SO_RCVTIMEO , @n , SizeOf(n))<>SOCKET_ERROR) and
       (ioctlsocket(Sock, FIONBIO, ul)<>SOCKET_ERROR) then begin
      Connect(Sock , SA , SizeOf(SA));
      FD_ZERO(FDSet);
      FD_SET(Sock , FDSet);
      TV.tv_sec := piTimeOut;
      TV.tv_usec := 0;
      Result := select(0, NIL , @FDSet , NIL , @TV)>0;
    end;
    CloseSocket(Sock);
  end;
end;

------解决方案--------------------
你是没有调用WSAStartup初始化,所以建立socket失败
参考:
Delphi(Pascal) code

uses WinSock;

function ScanTCPPort(ip: string; port: Word): Boolean;
var
  sin: sockaddr_in;
  li_socket, err: Integer;
  wVersionRequested: Word;
  wsaData: TWSAData;
begin
  Result := False;
  try
    wVersionRequested := MAKEWORD(2, 0);
    err := WSAStartup(wVersionRequested, wsaData);
    if ( err <> 0 ) then
      Exit;
    li_socket := socket(AF_INET,SOCK_STREAM, 0);
    if li_socket < 0 then
      Exit;

    ZeroMemory(@sin, sizeof(sin));
    sin.sin_family := AF_INET;
    sin.sin_addr.s_addr := inet_addr(PChar(ip));
    sin.sin_port := htons(port);
    if connect(li_socket, sin, sizeof(sin)) < 0 then
      Exit;
  finally
    closesocket(li_socket);
  end;
  Result := True;
end;