博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单的端口扫描器(TCP connect)
阅读量:5272 次
发布时间:2019-06-14

本文共 2023 字,大约阅读时间需要 6 分钟。

端口扫描器原理相对简单,采用的是TCP connect状态判断。具体来说:TCP connect方式使用系统网络API connect向目标主机的端口发起连接,如果无法连接,说明该端口关闭。该方式扫描速度比较慢,而且由于建立完整的TCP连接会在目标机上留下记录信息,不够隐蔽。所以,TCP connect是TCP SYN无法使用才考虑选择的方式。

在编写过程中,采用多线程时遇到共享变量访问的同步问题,经过试验,这里仅仅简单采用Sleep()函数进行等待就能拥有不错的效果。

代码及部分说明如下:

 

#include <stdio.h>

#include <WinSock2.h>

#include <time.h>

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

 

int gNumThread = 0;

 

void usage()

{

   printf("Usage: <TCPScanner> [IP] [StartPort]-[EndPort]\n");

   printf("Example: TCPScanner 192.168.1.1 80-100\n");

   ExitProcess(1);

}

 

DWORD WINAPI ThreadProc(LPVOID pPara);

 

int main(int argc, char *argv[])

{

   WSADATA wsad;

   SOCKADDR_IN target;

   char *IP,*p;

   USHORT PortEnd,PortStart,i;

   clock_t TimeStart,TimeEnd;

   HANDLE    hThread;

    DWORD    dwThreadId;

 

   //参数处理

   if(argc!=3) usage();

   IP = argv[1];  //第一个参数是IP

   PortStart = atoi(argv[2]);  //第二个参数是端口范围,分别得到首尾端口

   for(p = argv[2];*(p++)!='-';);  //指向结束端口的起始位置

   PortEnd = atoi(p);

 

   printf("Scanner will work on %s %d-%d now..\n",IP,PortStart,PortEnd);

   TimeStart = clock();

 

   //加载,创建套接字,填写目标主机地址,按端口扫描

   WSAStartup(MAKEWORD(2,2),&wsad);

   target.sin_family = AF_INET;

   target.sin_addr.s_addr = inet_addr(IP);

   for(i=PortStart;i<=PortEnd;++i){

        target.sin_port = htons(i);

        //创建进程接收数据

        hThread = CreateThread(NULL,0,ThreadProc,(LPVOID)&target,0,&dwThreadId);

        Sleep(10);  //主进程先等待一段时间,使得子进程能够有时间来读取端口信息,不致跳过、错开某些端口

        if (hThread == NULL){

            printf("CreateThread() failed: %d\n", GetLastError());

            break;

        }

        CloseHandle(hThread); //不再需要这个句柄,关掉它,但并非是关掉对应线程

   }

 

   Sleep(50);  //等待上一段时间,等待所有子进程结束任务

   TimeEnd = clock();

   printf("Time cost:%.3fs\n",(float)(TimeEnd-TimeStart)/CLOCKS_PER_SEC);

 

   WSACleanup();

   return 0;

}

 

DWORD WINAPI ThreadProc(LPVOID pParam)

{

   SOCKADDR_IN target = *(SOCKADDR_IN*) pParam;

   SOCKET sConn;

 

   printf("%s %d\n",inet_ntoa(target.sin_addr),ntohs(target.sin_port));

   sConn = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);

   if(connect(sConn,(const SOCKADDR*) &target,sizeof(target)) == SOCKET_ERROR) return 0;

   printf("Port %d is open\n",ntohs(target.sin_port));

             

   closesocket(sConn);

   return 0;

}

 

转载于:https://www.cnblogs.com/instona/p/3467585.html

你可能感兴趣的文章
【转】经验分享:大型高并发高负载网站的系统架构
查看>>
HDU 6060 RXD and dividing (求贡献)
查看>>
java中 immutable,future,nio
查看>>
VMware ESX常用命令
查看>>
golang三方包应该如何安装--在线和离线
查看>>
选择排序
查看>>
鼠标移入移出透明度变化效果
查看>>
POJ 3420 矩阵乘法
查看>>
POJ 3498 最大流
查看>>
github 添加fork
查看>>
【计算机视觉】双目测距(二)--双目标定与矫正
查看>>
【VS开发】开发最小化到托盘的功能
查看>>
【视频开发】【CUDA开发】FFMPEG硬件加速-nvidia方案
查看>>
win32之取画刷的方法
查看>>
Servlet
查看>>
IEDA-Git的应用
查看>>
iframe标签和frame标签异同
查看>>
JavaScripot frame
查看>>
表的操作
查看>>
Mysql 流程控制
查看>>