多线程端口扫描器

废话不多说,直接上源码。需要在cmd下传递参数

#include <stdio.h>
#include<winsock2.h>
#include <time.h>
#pragma comment(lib,"ws2_32.lib")

char *host;
int thread_num,thread_max,port_num;
long port_now;
TIMEVAL timeout; 
FD_SET    mask;

void introduc(char *name);
void display(void)  ;
void ThreadEnd(void);
DWORD WINAPI ThreadScan( LPVOID lp ); 

void main( int argc,char **argv ) 
{
         WSADATA ws;
     char *p;
         int port_start,port_end;
     if(argc!=4) //判断参数是否为4个
     {
         introduc(argv[0]);
         return ;
     }

     long result;
     result=WSAStartup(MAKEWORD(2,2), &ws);
        p=argv[2];//取得端口的范围
    if(strstr(argv[2],"-"))
    {    
                port_start=atoi(argv[2]);
        for(;*p;)
            if(*(p++)=='-')break;
        port_end=atoi(p);

        if(port_start<1 || port_end>65535)
        {    
                        printf("Port Error!\n");
            return;
        }
    }
    host=argv[1];
     thread_max=(atoi(argv[3])-1>999)?999:atoi(argv[3])-1;
        introduc(argv[0]);


        timeout.tv_usec=0;
        if(thread_max>500)timeout.tv_sec=2;
        else timeout.tv_sec=1;
        port_num=port_end-port_start; 
        printf("Loading......\n");
        for(int port=port_start;port<port_end;port++,port_now++,thread_num++)
        {
                 display(); 
                 while(thread_num>thread_max)Sleep(10);//当线程数大于最大线程数就等待一会
          CreateThread( NULL,0,ThreadScan,&port, 0,NULL);//创建扫描线程
        }
        printf("\n\n");
        ThreadEnd();
        WSACleanup();
        return ;
}

//介绍函数
void introduc(char *name) 
{
        printf("---------------------------------Portscaner---------------------------------\n");
        printf("\tplease input : %s,IP,port from start to end,thread_max(1000)\n",name);
        printf("\tExample: %s 192.168.1.1 1-10000 500\n",name);
        printf("---------------------------------Portscaner---------------------------------\n");
}
// 定义状态提示函数 
void display(void)  
{ 
        printf("%dthreads %d %s completed.\r",thread_num,port_now*100/(port_num+1),"%");
        Sleep(1);

} 
//关闭线程
void ThreadEnd(void)
{
        Sleep(1000);
        printf("\nThread ending....\n");
        while(thread_num>0)
         {
                      Sleep(1);
                          printf(" \t%d threads \r",thread_num);

          }
        printf("\nThread ended!\n");
}
//扫描函数 
DWORD WINAPI ThreadScan( LPVOID lp )
{   
        int port=*(DWORD*)lp; //取得要扫描的端口号
        SOCKET sock;
    struct sockaddr_in addr;

    u_long value;
    addr.sin_family =AF_INET;
        addr.sin_addr.s_addr =inet_addr(host);
    value=1;
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock==INVALID_SOCKET)
    {   
             printf("Socket error!\n");
         InterlockedExchangeAdd((long *)&thread_num,-1);//线程数减1
         return 0;
    }
    ioctlsocket(sock,FIONBIO,&value);//把sock设定为非阻塞模式
        addr.sin_port = htons(port);

    connect(sock,(struct sockaddr *) &addr, sizeof(addr));
        FD_ZERO(&mask);
    FD_SET(sock,&mask);
    value=select(0,NULL,&mask,NULL,&timeout);
    if(value==0 || value==-1)
    {    
                 closesocket(sock);
                 Sleep(50);
                    InterlockedExchangeAdd((long *)&thread_num,-1);
         return 0;

    }
    else 
   {
         shutdown(sock, 0); //阻止socket接收和发送数据
         printf("\t\tFound port %d open.\r\n",port);//打印扫到的端口
         closesocket(sock);
         Sleep(50);
         InterlockedExchangeAdd((long *)&thread_num,-1);
        }
    return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值