废话不多说,直接上源码。需要在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;
}