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

📄 multiplethreadportscan.c

📁 跨网段多线程扫描单一端口的程序源码
💻 C
字号:
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <winsock2.h> 
#include <windows.h>

#pragma comment(lib,"ws2_32.lib") 

#define ScanSpeed 20 //主线程等待时间 
#define RetryCount 3 //创建线程失败重试次数

/*-------------- 函数原型---------------*/
void usage(char * path);
DWORD WINAPI scan(LPVOID lp); 

typedef struct 
{
	unsigned long ip; 
	USHORT port;
}infor; 

int threadcount; 
int findcount; 

// 主函数入口
int main(int argc,char *argv[])
{
	int				ret;
	WSADATA			wsa; 
    infor			infor1; 
    int				MaxThread; 
    int				nowAddr, port; 
    int				min,max; 
    HANDLE			h; 
	DWORD			dwThreadID;
	unsigned long	startAddr, endAddr;
	int				reTryTime = 0;//创建线程失败已经重试次数
	DWORD           scantime;

    if( argc != 6 )
	{
		usage( argv[0] );
		exit(-1);
	}

    MaxThread = atoi(argv[5]);

	ret = WSAStartup( 0x0202, &wsa );     // 初始化winsock.dll
	if( ret ) 
	{
		printf( "WSAStartup failed! %d\n", WSAGetLastError() );
		exit(0);
	}

    // 定义扫描开始结束的端口
    min = atoi( argv[3] ); 
    max = atoi( argv[4] ); 

	startAddr = ntohl( inet_addr(argv[1]) );
	endAddr = ntohl( inet_addr(argv[2]) );

    // 判断端口是否在0-65535之间
    if( (min<0) || (max>65535) )
    {
		printf("\n");
		printf("Ports must between 0-65535!\n");

		usage( argv[0] );
		
		exit(-1);
    }

    threadcount=0; //线程计数器
    findcount=0; 
	scantime = GetTickCount();

    for( nowAddr = startAddr; nowAddr <= endAddr; nowAddr ++ )
	{ 
		infor1.ip = nowAddr;

		for( port = min; port <= max; port ++ )
		{
			infor1.port = port;

			//应该是while而不是if
			while( threadcount >= MaxThread )
			{
				Sleep( ScanSpeed ); 
			}

			h = CreateThread( NULL, 0, scan, &infor1, 0, &dwThreadID ); 

			//创建线程失败且重试次数未达到最大,则重新创建,否则漏报
			while( (h == NULL) && reTryTime < RetryCount )
			{ 
				printf("\nCreateThread error!\n");
				h = CreateThread( NULL, 0, scan, &infor1, 0, &dwThreadID );
			} 
			
			if( h != NULL )
			{
				threadcount ++;
				dwThreadID ++;

				CloseHandle( h );
			}

			Sleep( ScanSpeed );
			//printf( "Current thread is %d\n", threadcount );
		}
	}

	while( TRUE )
	{
		if( threadcount > 0 )
		{
			Sleep( ScanSpeed );
		}
		else
		{
			break;
		}
	}

	printf("\n\nScan End! Find PortCount:%d",findcount); 
    WSACleanup();

    return 0;
} 


/*--------------------帮助函数----------------------*/
void usage( char * path )
{ 
	printf("\n----------------------------------------"); 
	printf("\n Code By zhouzhen "); 
	printf("\n USAGE:%s <ip1> <ip2> <port1> <port2> <MaxThread>",path); 
	printf("\n----------------------------------------\n\n"); 
} 

DWORD WINAPI scan( LPVOID lp )
{

	SOCKET					sock;
	int						ret;
	struct sockaddr_in		sin;
	int						ntime = 1000;
	infor					*lpinfor  = (infor*)lp;
	
	sock = socket( AF_INET, SOCK_STREAM, 0 ); //创建socket
	if( sock == INVALID_SOCKET )
	{
		printf( "socket error: %d\n", WSAGetLastError() );

		threadcount --;//失败要减少当前线程数量
		return 0;
	}

	ret = setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&ntime, sizeof(ntime) ); //设置超时1s
	if( ret != 0 )
	{
		printf( "setsockopt failed: %d\n", WSAGetLastError() );
	}
	
	memset( &sin, 0, sizeof(sin) );

	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(lpinfor->ip); 
	sin.sin_port = htons(lpinfor->port);

	ret = connect( sock, (struct sockaddr*)&sin, sizeof(sin) );//connect连接

	if(!ret)
	{ 
		findcount ++; 
		printf("\nHost %s -> %d\n", (char*)inet_ntoa(sin.sin_addr), ntohs(sin.sin_port) ); 
	 } 
     
	 closesocket(sock);
	 threadcount--; 
	 return 0;
}

⌨️ 快捷键说明

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