⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpconnectscan.cpp

📁 “网络安全技术实践与代码详解”实例代码
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma  comment (lib, "ws2_32.lib")


// 端口结构,包括开始端口和结束端口
typedef struct _PortList
{
	unsigned int start_port;
	unsigned int end_port;
	unsigned short thread_id;
}PortList;

#define MAX_THREAD 60 // 定义最大线程数
char TargetIP[20]; // 目标机IP地址
unsigned int ThreadNum; // 扫描线程数
unsigned int StartPort;
unsigned int EndPort;


// 解析命令函数
void ParseCmd(int argc, char **argv)
{
	char *pdest;
    int result;
	int  ch = '-'; // 分隔符
	char startport[8];
	char endport[8];
	ZeroMemory(startport,8);
	ZeroMemory(endport,8);
	if(argc < 3 || argc >4)
	{
		printf("usage : %s [TargetIP] [StartPort-EndPort] [ThreadNum]\n");
	}
	else// 参数为3个时,默认线程数为1
	{
		
		strcpy(TargetIP,argv[1]); // 获取目标机IP
		pdest = strchr( argv[2], ch );
        result = pdest - argv[2] + 1; // 寻找‘-’的位置
		strncpy(startport,argv[2],result-1); // 提取开始端口
		strncpy(endport,argv[2]+result,strlen(argv[2])-result); // 提取结束端口
		StartPort = atoi(startport);
		EndPort = atoi(endport);
	}
	if(argc == 3)
	{
		ThreadNum = 1;
	}
	else
	{
		ThreadNum = atoi(argv[3]); // 提取线程数
		if(ThreadNum>MAX_THREAD)
		{
			printf("超出最大线程数范围(1-60)!\n");
			exit(0);
		}
	}
		
}
// 端口扫描线程
DWORD WINAPI ScanHost(LPVOID lpParam)
{
	WSADATA  wsd;
    // 初始化Winsock库
	if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("加载Winsock失败!\n");
        return 0;
    }
	unsigned int startport; // 每个线程的开始端口
	unsigned int endport; // 每个线程的结束端口
	unsigned short threadid; // 进程标志位
	PortList *pl;
	pl = (PortList *)malloc(sizeof(PortList));
	if(pl == NULL)
	{
		printf(" 不能分配足够的内存!\n");
		exit(0);
	}

	pl = (PortList *)lpParam;
	startport = pl->start_port;
	endport = pl->end_port;
	threadid = pl->thread_id;
    
	SOCKET   client_sock;
    struct sockaddr_in server;
	// 创建连接端口的套接字
	client_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (client_sock == INVALID_SOCKET)
    {
        printf("创建socket失败: %d\n", WSAGetLastError());
        return 0;
    }
    // 设置目标机相关参数
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(TargetIP);

	// 开始探测端口
	for( unsigned int i=startport; i<=endport; i++)
	{
		// 设置目标机端口
		server.sin_port = htons(i);
		if (connect(client_sock, (struct sockaddr *)&server, 
			sizeof(server)) == SOCKET_ERROR)
		{ // 连接不成功,端口未开放
		   	// printf("端口 %5d 未开放 ---Thread %d\n", i, threadid);
		}
		else
		{ // 连接成功,端口开放
			printf("端口 %5d 开放!! ---Thread %d\n",i ,threadid);
		}
		Sleep(1);
	}

	closesocket(client_sock);
	return NULL;

}
int main(int argc, char **argv)
{
	
	ParseCmd(argc,argv);

	unsigned int portnum = EndPort-StartPort+1; // 总共的端口数目
	if(portnum<ThreadNum)
	{
		printf("请确保总端口数目大于线程数!\n");
		exit(0);
	}


	PortList *pl;
	pl = (PortList *)malloc(sizeof(PortList));
	if(pl == NULL)
	{
		printf(" 不能分配足够的内存!\n");
		exit(0);
	}

    
    printf("\n开始扫描目标主机 %s  端口范围 %d-%d 线程数 %d\n\n",TargetIP,StartPort,EndPort,ThreadNum);
	int aver = portnum/ThreadNum; // 每个线程的端口数目
	DWORD dwStart = GetTickCount(); // 计时开始
	HANDLE h[MAX_THREAD]; // 线程句柄
	for(unsigned int i=0; i<ThreadNum; i++)
	{
		// 设置每个线程开始端口
		pl->start_port = StartPort + i*aver;
		pl->thread_id = i+1; // 线程ID
        // 设置每个线程结束端口
		if(i!=ThreadNum-1)
		{
			pl->end_port = StartPort + (i+1)*aver -1;
		}
		else
		{
			pl->end_port = EndPort;
		}
		// 创建扫描线程
		h[i] = CreateThread(NULL, 0, ScanHost, pl, 0, 0);
		Sleep(100);
	}
    
	// 等待线程全部结束
	WaitForMultipleObjects(ThreadNum,h,TRUE,INFINITE); 
    printf("\n 端口扫描消耗时间 : %d ms \n",GetTickCount()-dwStart);
	free(pl);
	return 1;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -