简单的端口扫描器(TCP connect)
端口掃描器原理相對(duì)簡(jiǎn)單,采用的是TCP connect狀態(tài)判斷。具體來說:TCP connect方式使用系統(tǒng)網(wǎng)絡(luò)API connect向目標(biāo)主機(jī)的端口發(fā)起連接,如果無法連接,說明該端口關(guān)閉。該方式掃描速度比較慢,而且由于建立完整的TCP連接會(huì)在目標(biāo)機(jī)上留下記錄信息,不夠隱蔽。所以,TCP connect是TCP SYN無法使用才考慮選擇的方式。
在編寫過程中,采用多線程時(shí)遇到共享變量訪問的同步問題,經(jīng)過試驗(yàn),這里僅僅簡(jiǎn)單采用Sleep()函數(shù)進(jìn)行等待就能擁有不錯(cuò)的效果。
代碼及部分說明如下:
#include <stdio.h>
#include <WinSock2.h>
#include <time.h>
#pragma comment(lib,"ws2_32.lib")
int gNumThread = 0;
void usage()
{
printf("Usage: <TCPScanner> [IP]
[StartPort]-[EndPort]
");
printf("Example: TCPScanner 192.168.1.1 80-100
");
ExitProcess(1);
}
DWORD WINAPI ThreadProc(LPVOID pPara);
int main(int argc, char *argv[])
{
WSADATA wsad;
SOCKADDR_IN target;
char *IP,*p;
USHORT
PortEnd,PortStart,i;
clock_t TimeStart,TimeEnd;
HANDLE hThread;
DWORD dwThreadId;
//參數(shù)處理
if(argc!=3) usage();
IP = argv[1]; //第一個(gè)參數(shù)是IP
PortStart = atoi(argv[2]); //第二個(gè)參數(shù)是端口范圍,分別得到首尾端口
for(p = argv[2];*(p++)!='-';); //指向結(jié)束端口的起始位置
PortEnd =
atoi(p);
printf("Scanner will work on %s %d-%d now..
",IP,PortStart,PortEnd);
TimeStart =
clock();
//加載,創(chuàng)建套接字,填寫目標(biāo)主機(jī)地址,按端口掃描
WSAStartup(MAKEWORD(2,2),&wsad);
target.sin_family
= AF_INET;
target.sin_addr.s_addr = inet_addr(IP);
for(i=PortStart;i<=PortEnd;++i){
target.sin_port
= htons(i);
//創(chuàng)建進(jìn)程接收數(shù)據(jù)
hThread =
CreateThread(NULL,0,ThreadProc,(LPVOID)&target,0,&dwThreadId);
Sleep(10); //主進(jìn)程先等待一段時(shí)間,使得子進(jìn)程能夠有時(shí)間來讀取端口信息,不致跳過、錯(cuò)開某些端口
if (hThread == NULL){
printf("CreateThread() failed: %d
", GetLastError());
break;
}
CloseHandle(hThread);
//不再需要這個(gè)句柄,關(guān)掉它,但并非是關(guān)掉對(duì)應(yīng)線程
}
Sleep(50); //等待上一段時(shí)間,等待所有子進(jìn)程結(jié)束任務(wù)
TimeEnd =
clock();
printf("Time cost:%.3fs
",(float)(TimeEnd-TimeStart)/CLOCKS_PER_SEC);
WSACleanup();
return 0;
}
DWORD WINAPI ThreadProc(LPVOID pParam)
{
SOCKADDR_IN target = *(SOCKADDR_IN*) pParam;
SOCKET sConn;
printf("%s %d
",inet_ntoa(target.sin_addr),ntohs(target.sin_port));
sConn = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(connect(sConn,(const SOCKADDR*) &target,sizeof(target)) == SOCKET_ERROR) return 0;
printf("Port %d is open
",ntohs(target.sin_port));
closesocket(sConn);
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的简单的端口扫描器(TCP connect)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iPhone 14赶不上了 台积电3nm
- 下一篇: 高端成了!吉利全新SUV官图发布:8分像