连上了就是开放,并且断开连接。连不上就是没有开放。
但是我又不想用控件,想直接用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
12 个解决方案
#1
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;
#2
你是没有调用WSAStartup初始化,所以建立socket失败
参考:
参考:
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;
#3
回1楼,代码测试不可用,也是怎么连都是false
回2楼 代码测试可用,请教怎么设置延迟?如果3秒延迟则放弃(放弃认为连不上)。
回2楼 代码测试可用,请教怎么设置延迟?如果3秒延迟则放弃(放弃认为连不上)。
#4
刚搞错了
2楼代码也不可用,不管连什么都是返回 True
2楼代码也不可用,不管连什么都是返回 True
#5
你不会没WSAStartup吧?
完整代码在这里
http://blog.csdn.net/kiboisme/article/details/6573984
完整代码在这里
http://blog.csdn.net/kiboisme/article/details/6573984
#6
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Winsock;
type
TForm1 = class(TForm)
Button2: TButton;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
piTimeOut:integer=3; //延迟
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 := piTimeOut * 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;
procedure TForm1.FormCreate(Sender: TObject);
var
WSA : TWSAData;
begin
WSAStartup(MakeWord(2,2),WSA);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if TryIPPort('110.75.161.108',16000) then ShowMessage('True') else ShowMessage('False');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if TryIPPort('110.75.161.108',9999) then ShowMessage('True') else ShowMessage('False'); //应该连不上的,他提示True
end;
//这个IP110.75.161.108 的16000是开放的 9999端口是关闭的 ,但是怎么连都返回True ,不信你试一下
end.
不信你看。。。。。。。。。。。。。
#7
#8
求解答,代码在6楼
#9
UP`````````````````````````````
#10
即使我用你的代码,在D7和D2010上面都运行了,都能正确反应情况,你要考虑你的环境了.!
#11
我WINXP SP3
#12
我也遇到六楼的问题了,无论对方机器端口开没开(甚至关着机呢),都能返回true
#1
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;
#2
你是没有调用WSAStartup初始化,所以建立socket失败
参考:
参考:
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;
#3
回1楼,代码测试不可用,也是怎么连都是false
回2楼 代码测试可用,请教怎么设置延迟?如果3秒延迟则放弃(放弃认为连不上)。
回2楼 代码测试可用,请教怎么设置延迟?如果3秒延迟则放弃(放弃认为连不上)。
#4
刚搞错了
2楼代码也不可用,不管连什么都是返回 True
2楼代码也不可用,不管连什么都是返回 True
#5
你不会没WSAStartup吧?
完整代码在这里
http://blog.csdn.net/kiboisme/article/details/6573984
完整代码在这里
http://blog.csdn.net/kiboisme/article/details/6573984
#6
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Winsock;
type
TForm1 = class(TForm)
Button2: TButton;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
piTimeOut:integer=3; //延迟
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 := piTimeOut * 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;
procedure TForm1.FormCreate(Sender: TObject);
var
WSA : TWSAData;
begin
WSAStartup(MakeWord(2,2),WSA);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if TryIPPort('110.75.161.108',16000) then ShowMessage('True') else ShowMessage('False');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if TryIPPort('110.75.161.108',9999) then ShowMessage('True') else ShowMessage('False'); //应该连不上的,他提示True
end;
//这个IP110.75.161.108 的16000是开放的 9999端口是关闭的 ,但是怎么连都返回True ,不信你试一下
end.
不信你看。。。。。。。。。。。。。
#7
#8
求解答,代码在6楼
#9
UP`````````````````````````````
#10
即使我用你的代码,在D7和D2010上面都运行了,都能正确反应情况,你要考虑你的环境了.!
#11
我WINXP SP3
#12
我也遇到六楼的问题了,无论对方机器端口开没开(甚至关着机呢),都能返回true