#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-";
struct RECVPAPAM{
int port_num;
char S_addr[20];
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); //关键代码段
// WaitForSingleObject(hMutex,INFINITE); //互斥对象
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); //关键代码段
return 0;
}
}
int main(){
int i=0,j,select;
char S_addr[20];
int port_nums[100];
char Thread_name[8]="Thread-";
int threads_num,port_num;
//加载套接字库
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; //新建线程句柄
printf("**************************************\n");
printf("* 欢迎使用网络端口扫描器 *\n");
printf("* 1.特定端口扫描 *\n");
printf("* 2.全端口扫描 *\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){
threads_num = 76; //线程数
port_num = 76*880; //端口数
printf("已准备创建%d个线程,扫描0-%d的端口号\n",threads_num,port_num);
}
else{
exit(0);
}
printf("要扫描端口号所对应的ip(格式:'ip'):\n");
scanf("%s",&S_addr);
getchar();
while(S_addr[i] != NULL){
pRecvParam->S_addr[i] = S_addr[i];
i++;
}
int q;
if(select != 2){
for(i=0;i<port_num;i++){
q = (i % threads_num);
pRecvParam->port_num = port_nums[i];
pRecvParam->i = q;
hThread_x = CreateThread(NULL,0,FunxProc,(LPVOID)pRecvParam,0,NULL); //创建接收线程
// 第五个参数:即线程创建标记,设置为零,但线程一旦创建就立即启动运行
CloseHandle(hThread_x); //关闭接收线程句柄
InitializeCriticalSection(&g_cs); //初始化关键代码段
Sleep(100); //关键代码段
DeleteCriticalSection(&g_cs); //关键代码段
}
}
else{
for(j = 0 ; j < 76*880 ; j++){
q = (j % threads_num) ;
pRecvParam->port_num = j +1;
pRecvParam->i = q;
hThread_x = CreateThread(NULL,0,FunxProc,(LPVOID)pRecvParam,0,NULL); //创建接收线程
// 第五个参数:即线程创建标记,设置为零,但线程一旦创建就立即启动运行
CloseHandle(hThread_x); //关闭接收线程句柄
InitializeCriticalSection(&g_cs); //初始化关键代码段
Sleep(100); //关键代码段
DeleteCriticalSection(&g_cs); //关键代码段
}
}
// hMutex = CreateMutex(NULL,FALSE,NULL); //创建互斥对象
// Sleep(4000); //互斥对象
return 0;
}