我想检测一个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
连上了就是开放,并且断开连接。连不上就是没有开放。但是我又不想用控件,想直接用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 取得日期和时间的控件
- 一个简单的数据库问题
- 有关pointer类型的数据的问题?
- 重叠I/O模型的WSAWaitForMultipleEvents只能处理64事件句柄怎么解决
- 求助:怎么样才能把文字做成图片,即输入你的文字,输出结果为一个这种文字的图片
- ComboBox问题?
- 如何将DecisionGraph1控件的横坐标和纵坐标改变为中文显示?
- 请教大侠:MIS系统实现的问题
- 怎么在webbrowser导航后,但没显示前,修改网页内容,修改完再显示。
- dephi里如何实现类似C语言的memset的功能?
- 如何填充完整的BMP格式图
- 请问DevExpress中的TdxNavBar中如何添加树或其他控件
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;
参考: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;
完整代码在这里
http://blog.csdn.net/kiboisme/article/details/6573984
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.
不信你看。