測試 IP 中的 PORT 是否開啟的問題 |
尚未結案
|
Komuro
一般會員 發表:27 回覆:46 積分:14 註冊:2004-02-19 發送簡訊給我 |
針對之前這篇測試 IP 中的 PORT 是否開啟
http://delphi.ktop.com.tw/topic.php?topic_id=33242
程式如下
uses Winsock; procedure TForm1.Button1Click(Sender: TObject);
procedure PortScan(AIP: string; APort: integer);
var
data: TWSAData;
sock: TSocket;
addr: TSockAddrIn;
iaddr: TInAddr;
begin
try
if (WSAStartup($0101, data) = 0) then
begin
sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock <> INVALID_SOCKET) then
begin
// zero out the addr struct.
FillChar(addr, SizeOf(TSockAddrIn), 0);
FillChar(iaddr, SizeOf(TInAddr), 0); //fill in the internet address
iaddr.S_addr := inet_addr(PChar(AIP)); //fill in the rest of the address.
addr.sin_family := PF_INET;
addr.sin_port := htons(APort);
addr.sin_addr := iaddr; // try to connect, if it failes then the port is closed
if (connect(sock, addr, SizeOf(TSockAddrIn)) = 0) then
begin
ShowMessage('Port ' IntToStr(APort) ' IS open on ' AIP);
end else
begin
ShowMessage('Port NOT open ' IntToStr(APort) ' on ' AIP);
end;
end else
begin
ShowMessage('There was an error creating the socket.');
end;
end else
begin
ShowMessage('Failed to initialize winsock.');
end;
finally
WSACleanup();
end;
end;
begin
Button1.Enabled := False;
PortScan('192.168.1.34', 80);
Button1.Enabled := True;
end;
本人在IdTCPserver.active = true時,由clinet端執行以上portscanv想看 IP 中的 PORT 是否開啟,但IDTCPServerExecute事件中SRequest := UpperCase(ReadLn)會出錯,我想應該是執行if (connect(sock, addr, SizeOf(TSockAddrIn)) = 0) then這行時server收不到回應的緣故,請問在這時(server啟動)portscan該如何修改才能用? 發表人 - Komuro 於 2004/04/16 16:16:00
|
microbean
初階會員 發表:1 回覆:43 積分:38 註冊:2004-04-09 發送簡訊給我 |
第一點 :
port Scan 這一段 code ,
以 winsock 理論來看 是一種不太友善的行為
因為 他在 connect 後立刻WSACleanup
這會導致 Disconnect 的訊號,沒有送給 Server
所以你在 indy 上, 會收到 Socket Error 10054 的錯誤訊息. 第二點 : indy 如果使用 readln , 他會一直等到 Terminator (預設是 #13#10)
出現才會往下走. 第三點 :
indy 在 Active = true 後 , 當 connection 進入 , 就會進入 Execute
的 procedure , 所以剛好遇到你的 readln , 然後就停在那邊等 Terminator . 所以問題不全然是 port scan 的錯 ,我比較傾向是 indy 的規劃不是很好.
因為 connect 後就直接進入 execute procedure ,會帶來一些困擾. 針對 port scan 修改..讓它成為友善的斷線 , 以及解掉 execute 的 readln procedure TForm1.Button1Click(Sender: TObject);
procedure PortScan(AIP: string; APort: integer);
var
data: TWSAData;
sock: TSocket;
addr: TSockAddrIn;
iaddr: TInAddr; //新的 buffer array
buff : array [0..6] of char; begin
try if (WSAStartup($0101, data) = 0) then
begin sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock <> INVALID_SOCKET) then
begin
// zero out the addr struct.
FillChar(addr, SizeOf(TSockAddrIn), 0);
FillChar(iaddr, SizeOf(TInAddr), 0); //fill in the internet address
iaddr.S_addr := inet_addr(PChar(AIP)); //fill in the rest of the address.
addr.sin_family := PF_INET;
addr.sin_port := htons(APort);
addr.sin_addr := iaddr; // try to connect, if it failes then the port is closed
if (connect(sock, addr, SizeOf(TSockAddrIn)) = 0) then
begin
//為了讓 indy Readln 可以讀的到,解掉 readln
buff := 'hello' #13#10;
if (send(sock ,buff ,sizeof(buff) , 0) = SOCKET_ERROR) then
begin
ShowMessage('Send Error');
end; //友善的關掉 socket
closeSocket(sock); ShowMessage('Port ' IntToStr(APort) ' IS open on ' AIP);
end else
begin
ShowMessage('Port NOT open ' IntToStr(APort) ' on ' AIP);
end; end else
begin
ShowMessage('There was an error creating the socket.');
end;
end else
begin
ShowMessage('Failed to initialize winsock.');
end; finally
WSACleanup();
end;
順帶一提 , 如果你要拿 port scan 做大量的 scan
可以把 WSAStartup WSACleanup , 拿出 PortScan 的
procedure , 只要在主程式的一開始 WSAStartup
主程式結束 WSACleanup 就好了 希望能有幫助
|
Komuro
一般會員 發表:27 回覆:46 積分:14 註冊:2004-02-19 發送簡訊給我 |
|
Ktop_Robot
站務副站長 發表:0 回覆:3511 積分:0 註冊:2007-04-17 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |