都是在 VS2015 實驗的
1、python 單線程
import socket
while True:
#引入協議族AF_INET和SOCK_STREAM
sm=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sm.settimeout(1)
ip = input("靶機ip:")
dk=input("靶機開始端口:")
startport = int(dk)
dk= input("靶機結束端口:")
endport = int(dk)
for port in range(startport, endport + 1):
print("正在掃描端口:%d" % port)
try:
sm.connect((ip, port))
print("服務器 %s 端口 %d 開啓!" % (ip, port))
except Exception:
print("服務器 %s 端口 %d 找不到!" % (ip, port))
sm.close()
2、C++ 單線程
// scanPort.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <winsock.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)
int main()
{
WORD wVersion = MAKEWORD(2, 0);
WSADATA wsaData;
struct sockaddr_in sin; //socket信息。
int iFromPort; //起始端口號
int iToPort; //截至端口號
int iNowPort; //正在處理的端口號
char cHost[20]; //IP
SOCKET s;
int iOpenPort; //統計開放的端口個數 。
iOpenPort = 0;
char choose; //是否存儲到文件中。
FILE *tp;
cout << "請輸入待檢測IP:";
cin >> cHost;
cout << "請輸入起始端口號:";
cin >> iFromPort;
cout << "請輸入截至端口號:";
cin >> iToPort;
cout << "是否把掃描結果保存到文件(y/n):";
cin >> choose;
if (choose == 'y')
{
tp = fopen("Out.txt", "w+");
fprintf(tp, "IP:%s 掃描結果如下:\n", cHost);
}
if (iFromPort > iToPort || iFromPort < 0 || iFromPort >65535 || iToPort <0 || iToPort >65535)
{
printf("端口號輸入錯誤!\n");
return 0;
}
if (WSAStartup(wVersion, &wsaData))
{
printf("初始化失敗!\n");
return -1;
}
printf("======= 開始掃描 ======= \n");
for (iNowPort = iFromPort; iNowPort <= iToPort; iNowPort++)
{
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET)
{
printf("創建socket()失敗! \n");
WSACleanup();
}
sin.sin_family = AF_INET;
sin.sin_port = htons(iNowPort);
sin.sin_addr.S_un.S_addr = inet_addr(cHost);
if (connect(s, (struct sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("%s -> %d:未開放 \n", cHost, iNowPort);
closesocket(s);
}
else
{
if (choose == 'y')
{
fprintf(tp, "端口:%d 開放\n", iNowPort);
}
printf("%s -> %d:開放 \n", cHost, iNowPort);
iOpenPort++;
closesocket(s);
}
}
printf("======= 掃描結果 ======= \n");
printf("主機:%s 掃描到%d個端口開放\n", cHost, iOpenPort);
if (choose == 'y')
{
fclose(tp);
}
closesocket(s);
WSACleanup();
return 0;
}
核心代碼:
3、C++多線程(掃描結果不準)
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#include <Windows.h>
#include <ws2tcpip.h>
#include <time.h>
#pragma comment(lib,"WS2_32.lib")
#pragma warning(disable : 4996)
DWORD WINAPI ScanThread(LPVOID port);
int main(int argc, char* argv[])
{
WSADATA wsd;
int port = 0;
int MAX_PORT;
clock_t start, end;
HANDLE handle;
DWORD dwThreadId;
//Initialize socket lib
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return 1;
}
printf("請輸入要掃描的最大端口:");
scanf("%d", &MAX_PORT);
printf("Scaning......\n");
start = clock();
//掃描的主要代碼,根據需要刪減
do {
handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ScanThread, (LPVOID)port, 0, &dwThreadId);
port++;
} while (port < MAX_PORT);
WaitForSingleObject(handle, INFINITE);//等待最後一個線程結束
end = clock();
int duration = end - start;
printf("總耗時 %d ms", duration);
system("pause");
return 0;
}
DWORD WINAPI ScanThread(LPVOID port)
{
int Port = (int)(LPVOID)port;
int retval;//調用各種socket函數的返回值
SOCKET sHost;
SOCKADDR_IN servAddr;
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sHost)
{
printf("socket failed!\n");
WSACleanup();
return -1;
}
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("123.125.115.110");
//setsockopt (sHost, IPPROTO_TCP, TCP_MAXRT, (char *)&Timeout, sizeof (Timeout));//設置快速掃描
servAddr.sin_port = htons(Port);
retval = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));//lpsockaddr is 環路地址
if (retval == SOCKET_ERROR) {
//printf("端口%d關閉!\n", Port); //這裏不要使用WSACleanup()函數,不然後續的線程會創建不了socket
closesocket(sHost);
return -1;
}
printf("端口%d開放!\n", Port);
closesocket(sHost);
return 1;
}
4、C++ 單線程
#include "stdafx.h"
#include <stdio.h>
#include<winsock.h>
#include<string.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"wsock32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "WSAStartup 無法初始化!" << endl;
return 0;
}
// 填寫遠程地址信息
sockaddr_in addr;
addr.sin_family = AF_INET;
while (true)
{
char aim_ip[100];
cout << "請輸入目的主機IP地址:";
cin >> aim_ip;
cout << endl;
//設置獲取的用戶輸入IP地址爲遠程IP地址
addr.sin_addr.S_un.S_addr = inet_addr(aim_ip);
int port_start;
int port_end;
cout << "請輸入起始端口號:";
cin >> port_start;
cout << endl;
cout << "請輸入結束端口號:";
cin >> port_end;
cout << endl;
for (int i = port_start; i <= port_end; i++)
{
//每掃描一個端口創建一個新的套接字
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
printf("Failed socket() %d \n", ::WSAGetLastError());
//return -1;
}
//設置遠程地址信息中的端口號爲需要掃描的當前端口號
addr.sin_port = htons(i);
int ret = connect(s, (LPSOCKADDR)&addr, sizeof(addr));
if (ret == 0)
{
printf("%s:%d 端口開啓\n", aim_ip, i);
}
else
{
printf("%s:%d 端口關閉\n", aim_ip, i);
}
::closesocket(s);
}
cout << endl;
}
if (WSACleanup() == SOCKET_ERROR)
cout << "WSACleanup 出錯!" << endl;
return 0;
}
參考: