python 和 c++ 实现网络端口扫描器 含windows平台和Linux平台

导读:本篇文章讲解 python 和 c++ 实现网络端口扫描器 含windows平台和Linux平台,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

网络端口扫描器 python && c++

介绍:输入端口号进行扫描,支持多线程,支持特定端口扫描或全端口扫描。
分别采用了 python和c++进行编写。
<1>#python Windows平台

#!/usr/bin/python3
import threading
import time
import socket

def getbanner(IP,port): #获得banner信息
    socket.setdefaulttimeout(2)
    s=socket.socket()
    try:
        s.connect((IP,port))
        threadLock.acquire()
        banner=s.recv(1024)
        threadLock.release()
        s.close()
        return banner
    except:
        pass

def checkbanner(banner):#检查banner信息
    if ("2.3.4" in banner):
        print (" banner信息:")
        print (banner)
    else:
        print ("banner信息无价值")

threadLock = threading.Lock() #锁对象:threading.Lock
threads = [] #线程列表
threads_num = 0

print("**************************************")
print("*        欢迎使用网络端口扫描器      *")
print("*           1.特定端口扫描           *")
print("*           2.全端口扫描             *")
print("*           0.退出                   *") 
print("**************************************")
select = float(input("请选择功能:"))


if select == 1:
    threads_num = int(input("请输入你要创建线程的数量:")) #线程数
    port_num = int(input("请输入要扫描的端口数量:")) #端口数
    threads_ip = input("要扫描端口号所对应的ip(格式:'ip'):")#目标Ip ip='127.0.0.1'
    port_nums = [0 for i in range(port_num + 1)] #一个用来放端口号的数组
    for i in range(port_num): #循环放入端口号
        port_nums[i + 1] = input("请输入要扫描的端口号:")

elif select == 2:
    threads_num = 76 #线程数
    port_num = 76*880 #端口数
    threads_ip = input("要扫描端口号所对应的ip(格式:'ip'):")#目标Ip ip='127.0.0.1'
    port_nums = [0 for i in range(port_num + 1)] #一个用来放端口号的数组
    for i in range(port_num): #循环放入端口号
        port_nums[i] = i
else:
    exit() 

def Thread_function(Thread_name,i):
    if (i <= port_num): 
        port =  port_nums[ i ]    #输入连接端口号
    print(">>>线程: %s 开始执行 记录时间:%s" % (Thread_name, time.ctime(time.time()))) #输出线程信息
    try: 
        print(">>>线程: {} 记录任务:正在扫描的端口号:{},端口号所对应的ip:{}".format(Thread_name,int(port) ,threads_ip)) 
        IP = threads_ip
        banner1=getbanner(IP,port)
        if banner1:
            checkbanner(banner1)
        else:
            print(">>>线程: {} 记录任务结果:没有获得banner信息".format(Thread_name))
    except Exception as e: 
        print (">>>线程: {} 扫描错误:{}".format(Thread_name,e))

print ("--------------------开始扫描--------------------")

if(select != 2):
    for n in range(0,port_num):
        q = (n % threads_num)+1   
        Thread_name = "Thread-"+str(q)
        port = port_nums[n + 1] 
        thread_x = threading.Thread(target = Thread_function,args = (Thread_name,n+1)) # 创建新线程
        threads.append(thread_x) # 添加 线程 到 线程列表
        thread_x.start() # 开启新线程,开始运行threading.Thread.run方法
else:
    for n in range(1,threads_num):
        Thread_name = "Thread-"+str(n)
        for p in range((n-1)*880,n*880): # 全端口扫描
            thread_x = threading.Thread(target = Thread_function,args = (Thread_name,p)) # 创建新线程
            threads.append(thread_x) # 添加 线程 到 线程列表
            thread_x.start() # 开启新线程,开始运行threading.Thread.run方法

# 等待所有线程完成
for t in threads:
    t.join() 

print ("--------------------扫描完成--------------------")

<2>#c++ Windows平台

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Winsock.h>

#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
char Thread_name[8]="Thread-";

int yes;
FILE *tp;
struct RECVPAPAM{
    int port_num;
    char *S_addr;
    int i;
};

HANDLE hMutex;    //互斥对象的句柄
RECVPAPAM *pRecvParam = new RECVPAPAM;
CRITICAL_SECTION g_cs; //定义一个关键区域结构体指针

DWORD WINAPI FunxProc(LPVOID ipParameter){ //线程数,端口,ip,某一个单线程的工作。

    // AF_INET:地址族 , SOCK_STREAM:套接字类型 , 0 传输协议
    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  //创建用于监听的套接字
    int i = pRecvParam->i;
    int port_num = pRecvParam->port_num;

    SOCKADDR_IN addrSrv;                              
    memset(&addrSrv, 0, sizeof(addrSrv));             //每个字节都用0填充
    addrSrv.sin_family = AF_INET;                      //使用IPv4地址
    addrSrv.sin_addr.S_un.S_addr = inet_addr(pRecvParam->S_addr);              //具体的IP地址
    addrSrv.sin_port = htons(port_num);                 //端口

    EnterCriticalSection(&g_cs);        //关键代码段
    Sleep(1);							   //关键代码段&&互斥对象 

    printf(">>>---------------线程:%s%d开始扫描----------------------------\n",Thread_name,i+1);
    printf(">>>线程:%s%d执行:记录开始任务:正在扫描端口号:%d\n",Thread_name,i+1,port_num);
   
    if(connect(sockClient,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) == SOCKET_ERROR){
        printf(">>>连接失败,结束此次连接\n");
        printf(" 记录结束任务:扫描端口号:%d失败\n",port_num);
        printf(">>>--------------------结束扫描----------------------------\n");
        closesocket(sockClient);                          //关闭套接字
        WSACleanup(); 
        return 0;
    } 
    else{
        printf(">>>连接成功正在获取信息\n");
        char recvBuf[100];                         //用于存放数据
        recv(sockClient,recvBuf, 100, 0);            // 接受数据
        printf("扫描端口号:%d,获得信息:%s\n",port_num,recvBuf);                         //输出接收的数据
        printf(" 记录结束任务:己扫描端口号:%d\n",port_num);
        printf(">>>--------------线程:%s结束扫描----------------------------\n",Thread_name);
        closesocket(sockClient);                          //关闭套接字
        WSACleanup();                                   //终止 DLL 的使用
        // ReleaseMutex(hMutex);               //互斥对象
        LeaveCriticalSection(&g_cs);       //关键代码段

        if(yes == 'y' || yes == 'Y'){     
            for(i=0;recvBuf[i] != 0;i++) {
                fseek(tp,i*sizeof(recvBuf[i]),0);
                fread(&recvBuf[i],sizeof(recvBuf[i]),1,tp); 
            }                 
        }
        return 0;
    }

}

DWORD WINAPI FunyProc(LPVOID ipParameter){ //线程数,端口,ip,某一个单线程的工作。

    // AF_INET:地址族 , SOCK_STREAM:套接字类型 , 0 传输协议
    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  //创建用于监听的套接字
    int i = pRecvParam->i;
    int port_num = pRecvParam->port_num;

    SOCKADDR_IN addrSrv;                              
    memset(&addrSrv, 0, sizeof(addrSrv));             //每个字节都用0填充
    addrSrv.sin_family = AF_INET;                      //使用IPv4地址
    addrSrv.sin_addr.S_un.S_addr = inet_addr(pRecvParam->S_addr);              //具体的IP地址
    addrSrv.sin_port = htons(port_num);                 //端口

    EnterCriticalSection(&g_cs);        //关键代码段
    Sleep(1);							   //关键代码段&&互斥对象 

    printf(">>>---------------线程:%s%d开始扫描-------------------------\n",Thread_name,i+1);
    printf(">>>线程:%s%d执行:记录开始任务:正在扫描端口号:%d\n",Thread_name,i+1,port_num);
    
    if(bind(sockClient,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) == SOCKET_ERROR){
        printf(">>>连接失败,结束此次连接\n");
        printf(">>>记录结束任务:扫描端口号:%d失败\n",port_num);
        printf(">>>--------------------结束扫描----------------------------\n");
        closesocket(sockClient);                          //关闭套接字
        WSACleanup(); 
        return 0;
    } 
    else{
        printf(">>>连接成功正在获取信息\n");
        char recvBuf[100];                         //用于存放数据
        int len = sizeof(SOCKADDR);
        SOCKADDR_IN addrClient;
        recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);            // 接受数据
        printf("扫描ip:%s,扫描端口号:%d,获得信息:%s\n",pRecvParam->S_addr,port_num,recvBuf);                         //输出接收的数据
        printf(" 记录结束任务:己扫描端口号:%d\n",port_num);
        printf(">>>--------------线程:%s结束扫描----------------------------\n",Thread_name);
        closesocket(sockClient);                          //关闭套接字
        WSACleanup();                                   //终止 DLL 的使用
        // ReleaseMutex(hMutex);               //互斥对象
        LeaveCriticalSection(&g_cs);       //关键代码段

        if(yes == 'y' || yes == 'Y'){     
            for(i=0;recvBuf[i] != 0;i++) {
                fseek(tp,i*sizeof(recvBuf[i]),0);
                fread(&recvBuf[i],sizeof(recvBuf[i]),1,tp); 
            }                 
        }

        return 0;
    }

}

char* add(char *result,char and,int i){ // 字符串运算函数
	int sum,len=0;
    while(result[len]){
        len++;
    }
    if(and == '+'){
        sum = result[len - 1] - 48 +i;
		printf("%d\n",sum);
        if(sum > 9 && result[len - 2]  == 9){
            result[len - 2] = 0 + 48;
            result[len -1] = sum%10 + 48;
        }
        else if(sum > 9){
            result[len - 2] = result[len - 2] + 1 + 48;
            result[len - 1] = sum%10 + 48;
        }
        else{
            result[len - 1] = sum + 48;
        }
    }
    else{
        printf("请输入运算符\n");
    }

    return result;
}


void passward(){     /*请输入密码*/
   int x1,k=4,password;
   password=0;
   while(k>0)    
   {    
      printf("**请输入密码(初始密码为0):");
      scanf("%d",&x1);
      if(x1!=password)
      {    
         printf("**密码错误,还有%d次机会\n",--k);
         if(k==0)
            {printf("四次输入失败,退出程序.\n");exit(1);}
      }
         else {printf("**欢迎使用本系统!\n");k=0;}
   }
}

int main(){
    int q,w;
    int i=0,j,select,selece_ip;
    int select_type;
    char *S_addrs[50];
    
    int ip_num;
    int port_start,port_end;
    int port_nums[100];
    char Thread_name[8]="Thread-";
    int threads_num,port_num;
    int time_thread = 100,select_set;

    //加载套接字库           
    WORD wVersuinRequested;         //用来准备加载的Winsock库的版本。
    WSADATA wsaData;                //指向WSADATA结构体的指针。
    
    wVersuinRequested = MAKEWORD(1, 1); 
    if(WSAStartup(wVersuinRequested, &wsaData)){
        WSACleanup();
        printf("winsock 初始化失败\n");
        exit(0);
    }

    if(LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion)!= 1){
        WSACleanup();                                   //终止 DLL 的使用
        printf("winsock 初始化失败\n");
        exit(0);
    }
    HANDLE hThread_x; //新建线程句柄
    
    passward();
    while(true){
        /*1.TCP*/
        printf("**************************************\n");
        printf("*       欢迎使用网络端口扫描器       *\n");
        printf("*         1.基于TCP                  *\n");
        printf("*         2.基于UDP                  *\n");
        printf("*         0.退出                     *\n");
        printf("**************************************\n");
        printf("请选择类型:");
        scanf("%d",&select_type);
        if(select_type == 0){
            exit(0);
        }
        else if(select_type != 2 && select_type != 1){
            printf("由于未选择类型,网络端口扫描器将默认基于TCP\n");
            select_type = 1;     
        }
        
        
        /*2.端口*/
        printf("**************************************\n");
        printf("*       欢迎使用网络端口扫描器       *\n");
        printf("*         1.特定端口扫描             *\n");
        printf("*         2.选定段端口扫描           *\n");
        printf("*         3.全端口扫描               *\n");
        printf("*         0.退出                     *\n");
        printf("**************************************\n");
        printf("请选择功能:");
        scanf("%d",&select);
        if (select == 1){
            printf("请输入你要创建线程的数量:\n");
            scanf("%d",&threads_num);
            printf("请输入要扫描的端口数量:\n");
            scanf("%d",&port_num);
            for(i=0;i<port_num;i++){
                printf("请输入第%d个要扫描的端口号:",i+1);
                scanf("%d",&port_nums[i]);
            }
        }
        else if (select == 2){      
            printf("请输入你要创建线程的数量:\n");
            scanf("%d",&threads_num);         //线程数
            printf("请输入你要扫描的起始端口:\n");
            scanf("%d",&port_start);
            printf("请输入你要扫描的结束端口:\n");
            scanf("%d",&port_end);
            port_num =  port_end-port_start;      //端口数
            printf("已准备创建%d个线程,扫描%d-%d的端口号\n",threads_num,port_start,port_end);
            for(i=0;i<port_num;i++){
                port_nums[i] = port_start + i;
            }
        }
        else if (select == 3){
            threads_num = 76;         //线程数
            port_num =  76*880;      //端口数
            printf("已准备创建%d个线程,扫描0-%d的端口号\n",threads_num,port_num);
        }
        else{
            exit(0);
        }
        
        /*3.参数设置*/
        printf("扫描结果是否存储到文件(y or n)\n");
        scanf("%s",&yes);
        if(yes == 'y' || yes == 'Y'){
            if((tp = fopen("out.txt","a")) == NULL){
                printf("文件无法打开,无法写入文件\n");
            }           
            else{
                printf("文件已经打开,准备写入文件\n");
            }
        }
        while (true){
            printf("****************************************\n");
            printf("*           *参数设置选项*			   *\n");
            printf("* 1.设置每个线程最大扫描时间(默认100ms)*\n");
            printf("*         0.退出参数设置               *\n");
            printf("****************************************\n");
            printf("请选择功能:");
            scanf("%d",&select_set);
            if(select_set == 1){
                printf("请设置每个线程最大扫描时间:");
                scanf("%d",&time_thread);
            }
            else{
                break;
            }
        }
        
        /*4.ip*/
        printf("****************************************\n");
        printf("*       选择要进行扫描的主机ip         *\n");  
        printf("*         1.选定IP数量扫描             *\n");
        printf("****************************************\n");
        printf("选择IP扫描模式:\n");
        scanf("%d",&selece_ip);
        
        printf("选择要扫描的ip数量\n");
        scanf("%d",&ip_num);
        for(i=0;i<ip_num;i++){
            printf("要扫描端口号所对应的ip(格式:'ip'):\n");
            scanf("%s",&S_addrs[i]); 
            
        }          
        getchar();
        
        /*5.run*/
        for(w=0;w < ip_num;w++){       
            pRecvParam->S_addr = S_addrs[w];
            printf("=================================================\n");
            printf(">>>正扫描第%d个ip地址\n",w+1);
            if(select != 3){
                for(i=0;i<port_num;i++){
                    q = (i % threads_num);  
                    pRecvParam->port_num = port_nums[i];                       
                    pRecvParam->i = q;     
                    if(select_type == 1){
                        hThread_x = CreateThread(NULL,0,FunxProc,(LPVOID)pRecvParam,0,NULL);    //创建接收线程 
                    }   
                    else{
                        hThread_x = CreateThread(NULL,0,FunyProc,(LPVOID)pRecvParam,0,NULL);    //创建接收线程 
                    }           

                    // 第五个参数:即线程创建标记,设置为零,但线程一旦创建就立即启动运行
                    CloseHandle(hThread_x);         //关闭接收线程句柄 
                    InitializeCriticalSection(&g_cs);  //初始化关键代码段
                    Sleep(time_thread);                          //关键代码段
                    DeleteCriticalSection(&g_cs);      //关键代码段 
                }
            }
            else{                
                for(j = 0 ; j < 76*880 ; j++){
                    q = (j % threads_num) ;           
                    pRecvParam->port_num = j +1;                  
                    pRecvParam->i = q;       
                    if(select_type == 1){
                        hThread_x = CreateThread(NULL,0,FunxProc,(LPVOID)pRecvParam,0,NULL);    //创建接收线程 
                    }   
                    else{
                        hThread_x = CreateThread(NULL,0,FunyProc,(LPVOID)pRecvParam,0,NULL);    //创建接收线程 
                    }   
                    // 第五个参数:即线程创建标记,设置为零,但线程一旦创建就立即启动运行
                    CloseHandle(hThread_x);                                  //关闭接收线程句柄 
                    InitializeCriticalSection(&g_cs);  //初始化关键代码段
                    Sleep(time_thread);                          //关键代码段
                    DeleteCriticalSection(&g_cs);      //关键代码段 
                }  
            }     
            printf(">>>第%d个ip地址扫描结束\n",w+1);
            printf("=================================================\n");    
        }

        if(yes == 'y' || yes == 'Y'){
            fclose(tp);         
        } 
    }
    return 0;
}

<3>#c++ Linux平台

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <iostream>
#include <cstdlib>
using namespace std;
#define NUM_THREADS 40
struct thread_data{
    char *thread_id; 
    int  thread_port; 
    int threads_i; 
};
FILE *tp;
pthread_mutex_t mutex_x=PTHREAD_MUTEX_INITIALIZER;//静态初始化互斥锁

int *connect_Thread_TCP(int *threadarg){
    pthread_mutex_lock(&mutex_x);//通过互斥锁实现操作
    struct thread_data *my_data;
    my_data = (struct thread_data *) threadarg;
    int port,threads_i;
    char *s_addr;
    port = my_data->thread_port ;
    s_addr = my_data->thread_id ;
    threads_i = my_data->threads_i;
 

    // PF_INET:地址族 , SOCK_STREAM:套接字类型 , 0 传输协议
    int sockClient;
    sockClient = socket(AF_INET, SOCK_STREAM, 0); //创建用于监听的套接字

    struct sockaddr_in addrSrv;                             
    memset(&addrSrv, 0, sizeof(addrSrv));             //每个字节都用0填充
    addrSrv.sin_family = AF_INET;                      //使用IPv4地址
    addrSrv.sin_addr.s_addr = inet_addr(s_addr);              //具体的IP地址 //error
    addrSrv.sin_port = htons(port);                 //端口


    printf(">>>---------------开始扫描----------------------------\n");
    printf(">>>线程执行:记录开始任务:正在扫描的端口号:%d\n",port);
    
    if(connect(sockClient,(struct sockaddr*)&addrSrv, sizeof(addrSrv)) == -1){
        printf(">>>连接失败,结束此次连接\n");
        printf(" 记录结束任务:扫描端口号:%d失败\n",port);
        printf(">>>--------------------结束扫描----------------------------\n");
    }
    else{
		int  sockfd ;
    	int  end_index;							//用于存放数据
    	char message[4096];		// 接受数据
    	struct sockaddr_in  addrSrv;

		end_index = recv(sockClient, message, 4096, 0); 
        if(end_index==-1){
            printf("读取数据失败\n");
        }
        else{
			message[end_index] = '\0';
            printf(">>>连接成功正在获取信息\n");               
            printf("扫描端口号:%d,获得信息:%s\n",port,message);                         //输出接收的数据
            printf(" 记录结束任务:己扫描端口号:%d\n",port);
            printf(">>>--------------线程:结束扫描----------------------------\n");
        }                        
    }
    close(sockClient);                          //关闭套接字
    pthread_mutex_unlock(&mutex_x);//解锁
    pthread_exit(NULL);
    return 0;
}

int *connect_Thread_UDP(int *threadarg){
    pthread_mutex_lock(&mutex_x);//通过互斥锁实现操作
    struct thread_data *my_data;
    my_data = (struct thread_data *) threadarg;
    int port,threads_i;
    char *s_addr;
    port = my_data->thread_port ;
    s_addr = my_data->thread_id ;
    threads_i = my_data->threads_i;
 

    // PF_INET:地址族 , SOCK_STREAM:套接字类型 , 0 传输协议
    int sockClient;
    sockClient = socket(PF_INET, SOCK_STREAM, 0); //创建用于监听的套接字

    struct sockaddr_in addrSrv;                             
    memset(&addrSrv, 0, sizeof(addrSrv));             //每个字节都用0填充
    addrSrv.sin_family = AF_INET;                      //使用IPv4地址
    addrSrv.sin_addr.s_addr = inet_addr(s_addr);              //具体的IP地址 //error
    addrSrv.sin_port = htons(port);                 //端口


    printf(">>>---------------开始扫描----------------------------\n");
    printf(">>>线程执行:记录开始任务:正在扫描的端口号:%d\n",port);
    
    if(connect(sockClient,(struct sockaddr*)&addrSrv, sizeof(addrSrv)) == -1){
        printf(">>>连接失败,结束此次连接\n");
        printf(" 记录结束任务:扫描端口号:%d失败\n",port);
        printf(">>>--------------------结束扫描----------------------------\n");
    }
    else{
		int sock_fd; 
  		char message[4096];
  		int send_num;  
  		int recv_num;
  		int len;
  		struct sockaddr_in addrSrv; 
  		len = sizeof(addrSrv); 

		recv_num = recvfrom(sock_fd, message, sizeof(message), 0, (struct sockaddr *)&addrSrv, (socklen_t *)&len);  
  		if(recv_num < 0){  
  		  printf("读取数据失败\n");
		}
		else{
			message[recv_num] = '\0';
			printf(">>>连接成功正在获取信息\n");               
            printf("扫描端口号:%d,获得信息:%s\n",port,message);                         //输出接收的数据
            printf(" 记录结束任务:己扫描端口号:%d\n",port);
            printf(">>>--------------线程:结束扫描----------------------------\n");
		}                       
    }
    close(sockClient);                          //关闭套接字
    pthread_mutex_unlock(&mutex_x);//解锁
    pthread_exit(NULL);
    return 0;
}


void passward(){     /*请输入密码*/
   int x1,k=4,password;
   password=0;
   while(k>0)    
   {    
      printf("**请输入密码(初始密码为0):");
      scanf("%d",&x1);
      if(x1!=password)
      {    
         printf("**密码错误,还有%d次机会\n",--k);
         if(k==0)
            {printf("四次输入失败,退出程序.\n");exit(1);}
      }
         else {printf("**欢迎使用本系统!\n");k=0;}
   }
}

int main(){
    int i=0,j,select,threads_i,w;
    int rc,yes,selece_ip;
    char s_addr[20],s_addrs[50][20];
    char *ip_start,*ip_end;
    int ip_num;
    int *port_count;
    int port_num,port_nums[999];
    int port;
    int threads_num;
    pthread_t threads[NUM_THREADS];   
    struct thread_data td[NUM_THREADS];
	int port_start,port_end;
    int time_thread = 100,select_set,select_type;;
    
	passward();
	while(true){
		printf("**************************************\n");
        printf("*       欢迎使用网络端口扫描器       *\n");
        printf("*         1.基于TCP                  *\n");
        printf("*         2.基于UDP                  *\n");
        printf("*         0.退出                     *\n");
        printf("**************************************\n");
        printf("请选择类型:");
        scanf("%d",&select_type);
        if(select_type == 0){
            exit(0);
        }
       else{
            printf("由于未选择类型,网络端口扫描器将默认基于TCP\n");
            select_type = 1;          
        }
        

		printf("**************************************\n");
        printf("*       欢迎使用网络端口扫描器       *\n");
        printf("*         1.特定端口扫描             *\n");
        printf("*         2.选定段端口扫描           *\n");
        printf("*         3.全端口扫描               *\n");
        printf("*         0.退出                     *\n");
        printf("**************************************\n");
        printf("请选择功能:");
        scanf("%d",&select);

		if (select == 1){
            printf("请输入你要创建线程的数量:\n");
            scanf("%d",&threads_num);
            printf("请输入要扫描的端口数量:\n");
            scanf("%d",&port_num);
            for(i=0;i<port_num;i++){
                printf("请输入第%d个要扫描的端口号:",i+1);
                scanf("%d",&port_nums[i]);
            }
        }
        else if (select == 2){      
            printf("请输入你要创建线程的数量:\n");
            scanf("%d",&threads_num);         //线程数
            printf("请输入你要扫描的起始端口:\n");
            scanf("%d",&port_start);
            printf("请输入你要扫描的结束端口:\n");
            scanf("%d",&port_end);
            port_num =  port_end-port_start;      //端口数
            printf("已准备创建%d个线程,扫描%d-%d的端口号\n",threads_num,port_start,port_end);
            for(i=0;i<port_num;i++){
                port_nums[i] = port_start + i;
            }
        }
        else if (select == 3){
            threads_num = 76;         //线程数
            port_num =  76*880;      //端口数
            printf("已准备创建%d个线程,扫描0-%d的端口号\n",threads_num,port_num);
        }
        else{
            exit(0);
        }
        
		printf("扫描结果是否存储到文件(y or n)\n");
        scanf("%s",&yes);
        if(yes == 'y' || yes == 'Y'){
            if((tp = fopen("out.txt","a")) == NULL){
                printf("文件无法打开,无法写入文件\n");
            }           
            else{
                printf("文件已经打开,准备写入文件\n");
            }
        }

		while (true){
            printf("****************************************\n");
            printf("*           *参数设置选项*			   *\n");
            printf("* 1.设置每个线程最大扫描时间(默认100ms)*\n");
            printf("*         0.退出参数设置               *\n");
            printf("****************************************\n");
            printf("请选择功能:");
            scanf("%d",&select_set);
            if(select_set == 1){
                printf("请设置每个线程最大扫描时间:");
                scanf("%d",&time_thread);
            }
            else{
                break;
            }
        }
		
		printf("****************************************\n");
        printf("*       选择要进行扫描的主机ip         *\n"); 
        printf("*         1.选定IP数量扫描             *\n");
        printf("****************************************\n");
        printf("选择IP扫描模式:\n");
        scanf("%d",&selece_ip);
        
        printf("选择要扫描的ip数量\n");
        scanf("%d",&ip_num);
        for(i=0;i<ip_num;i++){
            printf("要扫描端口号所对应的ip(格式:'ip'):\n");
            scanf("%s",&s_addrs[i]); 
        }          
        getchar();
        pthread_attr_t attr;
        

		for(w=0;w < ip_num;w++){
            printf("=================================================\n");
            printf(">>>正扫描第%d个ip地址\n",w+1);
            td[w].thread_id = s_addrs[w];
			if(select != 3){
            	for(i=0;i<port_num;i++){
    	    		threads_i = (i % threads_num) + 1;      
    	    		td[i].thread_port = port_nums[i];
    	    		td[i].threads_i = threads_i;
					if(select_type == 1){
						rc = pthread_create(&threads[threads_i], NULL,connect_Thread_TCP, (int  *)&td[i]);//error
					}
					else{
						rc = pthread_create(&threads[threads_i], NULL,connect_Thread_UDP, (int  *)&td[i]);//error
					}	    	
    	    		/*重点:在编译中要加-lpthread参数*/
    	    		if (rc){         
    	    	        printf("错误:无法创建线程\n");          
    	    	        exit(-1);      
    	    	    } 
                    sleep(time_thread);                          //关键代码段
    			}  
			}      
            else{                
                for(i = 0 ; i < 76*880 ; i++){
                	threads_i = (i % threads_num) + 1;      
    	    		td[i].thread_port = i + 1;
    	    		td[i].threads_i = threads_i;
					if(select_type == 1){
                        printf("enter\n");
						rc = pthread_create(&threads[threads_i], NULL,connect_Thread_TCP, (int  *)&td[i]);//error
					else{
						rc = pthread_create(&threads[threads_i], NULL,connect_Thread_UDP, (int  *)&td[i]);//error
					}	    	
    	    		/*重点:在编译中要加-lpthread参数*/
    	    		if (rc){         
    	    	        printf("错误:无法创建线程\n");          
    	    	        exit(-1);      
    	    	    } 
                    sleep(time_thread);                          
    			}  
            }         
            printf(">>>第%d个ip地址扫描结束\n",w+1);
            printf("=================================================\n");
        }

        pthread_exit(NULL);
    }
	if(yes == 'y' || yes == 'Y'){
        fclose(tp);         
    } 
    return 0;
}
/* g++ main.cpp -lpthread -o main.out   ./main.out*/
/*重点:在编译中要加-lpthread参数*/

 /* pthread_create (thread, attr, start_routine, arg);
                        参数	描述
                       thread	指向线程标识符指针。
                        attr	一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。
                    start_routine	线程运行函数起始地址,一旦线程被创建就会执行。
                        arg	   运行函数的参数。它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。*/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92746.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!