Chinaunix首页 | 论坛 | 博客
  • 博客访问: 581106
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-04-01 23:19:21

先把代码贴出来,详细的流程与注释明天再写
首先是服务器端的代码,程序的主体部分是客户端的多线程扫描,所以服务器端的代码编写的相对简单,没有过多的安全性检查的处理。

// my_server.cpp 
// g++ my_server.cpp -o server

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <unistd.h>
  7. #include <arpa/inet.h>

  8. int main (int c , char ** v)
  9. {
  10.     struct sockaddr_in server_addr ;
  11.     int sockfd ;
  12.     
  13.     sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ;

  14.         server_addr.sin_family = AF_INET ;
  15.         server_addr.sin_port = htons (1027) ;
  16.         inet_aton ("127.0.0.1" , &server_addr.sin_addr ) ;

  17.         bind (sockfd ,(struct sockaddr*)&server_addr , sizeof(struct sockaddr_in) ) ;
  18.         listen ( sockfd , 10 ) ;

  19.     for (;;) {}
  20.     
  21.     return 0 ;
  22. }



// 后面的代码均属于 client 端,使用Makefile 进行编译
// Makefile

点击(此处)折叠或打开

  1. CPPFLAGS = -O3
  2. LDFLAGS = -lpthread

  3. all: Main

  4. clean :
  5.     rm -f *.o

  6. Main: Main.o my_scanner.o
  7.     g++ -o $@ $^ $(LDFLAGS)

// my_scanner.h

点击(此处)折叠或打开

  1. // my_scanner.h
  2. #ifndef MY_SCANNER_H
  3. #define MY_SCANNER_H

  4. #include <cstdio>
  5. #include <cstring>
  6. #include <cstdlib>

  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <unistd.h>
  11. #include <arpa/inet.h>
  12. #include <errno.h>

  13. #include <pthread.h>
  14. #include <vector>


  15. struct _scan_segment
  16. {
  17.    unsigned short int from_port ;
  18.    unsigned short int to_port ;
  19.    struct in_addr scan_addr ;    
  20. } ;

  21. typedef _scan_segment scanSegment ;


  22. class Scanner
  23. {
  24.   private :
  25.     std::vector<pthread_t> pthreadList ;
  26.     int threadNum ;
  27.     int      connfd ;    
  28.     struct in_addr scan_addr ;
  29.     int scan_max_port ;
  30.     int        scan_len ;
  31.     
  32.   public :
  33.     Scanner ( int _threadNum , struct in_addr _scan_addr , int _scan_max_port ) ;

  34. // static    int do_scan ( struct sockaddr_in ) ;
  35. //    void * scanner ( void *) ;    
  36.     void run ( void ) ;

  37. } ;

  38. #endif // my_scanner.h
// myscanner.cpp

点击(此处)折叠或打开

  1. // myscanner.cpp
  2. #include "my_scanner.h"

  3. using namespace std ;

  4. static void log_info ( const char *err_info , int location )
  5. {
  6.     fprintf (stderr, "[error]: %s, [line]: %d\n" ,     err_info , location) ;
  7.     perror ("exit function errinfo ") ;
  8.     exit ( 1 ) ;
  9. }


  10. Scanner::Scanner ( int _threadNum , struct in_addr _scan_addr , int _scan_max_port )
  11. {
  12.     
  13.     threadNum = _threadNum ;
  14.     scan_max_port = _scan_max_port ;
  15.     

  16.     if ( threadNum > scan_max_port )
  17.         threadNum = scan_max_port ;

  18.     scan_len = scan_max_port / threadNum ;
  19.     

  20.     // copy addr
  21.     scan_addr = _scan_addr ;    
  22.     
  23.     for ( int i = 0 ; i < threadNum ; i++ )
  24.     {    
  25.         pthread_t thread ;
  26.         pthreadList.push_back ( thread ) ;
  27.     }
  28. }


  29. int do_scan ( struct sockaddr_in dest_addr )
  30. {
  31.     int ret , conn_fd = socket ( AF_INET , SOCK_STREAM , 0 ) ;
  32.     
  33.     if ( conn_fd < 0 )
  34.          log_info ("socket" , __LINE__) ;

  35.     ret = connect ( conn_fd , (struct sockaddr *)&dest_addr ,
  36.                 sizeof ( struct sockaddr_in )) ;
  37.      if ( ret < 0 )
  38.      {
  39.         if ( errno == ECONNREFUSED )
  40.         {
  41.             close (conn_fd ) ;
  42.             return -1; // target port refused service
  43.         }
  44.         else
  45.         {
  46.             close ( conn_fd ) ;
  47.             return -2; // other error type
  48.         }

  49.      }
  50.     else
  51.     {
  52.         
  53.         printf ("port %d found in %s \n" , ntohs(dest_addr.sin_port) , inet_ntoa(dest_addr.sin_addr)) ;
  54.         close (conn_fd) ;
  55.         return 1 ;
  56.     }
  57.     return 0 ;
  58. }


  59. void* scanner ( void *arg )
  60. {
  61.     unsigned short int i ;
  62.     scanSegment scan_segment ;
  63.     struct sockaddr_in dest_addr ;
  64.     
  65.     memcpy ( &scan_segment , arg , sizeof ( scanSegment )) ;
  66.     
  67.     dest_addr.sin_family      = AF_INET ;
  68.     dest_addr.sin_addr = scan_segment.scan_addr ;    
  69.     
  70.     for ( i = scan_segment.from_port ; i != scan_segment.to_port ; i++ )
  71.     {
  72.         dest_addr.sin_port = htons ( i ) ;
  73.         
  74.         printf ("detected by thread %lu , results :\n" , pthread_self() ) ;
  75.     
  76.         switch ( do_scan ( dest_addr ) )
  77.         {
  78.             case -1 :
  79.                 printf ("refused service\n" ,i ) ;
  80.             break ;
  81.             
  82.             case -2 :
  83.                 printf ("other type error \n" , i ) ;
  84.             break ;
  85.             
  86.             case 1:
  87.                 printf ("check port %d free " , i ) ;            
  88.             break ;
  89.             default :
  90.                 printf ("unknown error \n") ;    
  91.         }
  92.             
  93.     }
  94.     
  95. }

  96. void Scanner::run ()
  97. {
  98.     scanSegment segment ;
  99.     segment.scan_addr = scan_addr ;
  100.     
  101.     
  102.     for ( int i = 0 ; i < threadNum ; i++ )
  103.     {
  104.         segment.from_port = i*scan_len + 1 ;
  105.         
  106.         if ( i == threadNum -1 )
  107.         {
  108.             segment.to_port = scan_max_port ;    
  109.         }
  110.         else
  111.         {
  112.             segment.to_port = segment.from_port + scan_len -1 ;
  113.         }
  114.         
  115.         if ( pthread_create ( &pthreadList[i] , NULL , scanner , (void *)&segment ) )
  116.         {
  117.             log_info ("pthread_create" , __LINE__) ;
  118.         }
  119.         
  120.         pthread_join ( pthreadList[i] , NULL ) ;
  121.     }
  122. }
// Main.cpp

点击(此处)折叠或打开

  1. // Main.cpp

  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <netinet/in.h>
  6. #include <sys/socket.h>
  7. #include <sys/types.h>
  8. #include <arpa/inet.h>

  9. #include "my_scanner.h"

  10. using namespace std ;

  11. void usage_info ( void )
  12. {
  13.     printf ("method usage : \n") ;
  14.     printf ("[-m][max port ]\t [-a][server address \"xxx.xxx.xxx.xxx\"]\t [-n][-thread number] \n") ;
  15. }


  16. int main ( int argc , char *argv[] )
  17. {
  18.   int i ;
  19.   int max_port ; // -m
  20.   int thread_num ; // -n
  21.   struct in_addr destAddr ; // -a
  22.  
  23.   Scanner *myScanner ;
  24.    

  25.   for ( i = 0 ; i < argc ; i++ )
  26.   {
  27.      if ( strcmp ( "-m" , argv[i] ) == 0 )
  28.      {
  29.         max_port = atoi (argv[i+1]) ;
  30.          if ( max_port < 0 || max_port > 65536 )
  31.         {
  32.             perror (" invalid port number ") ;
  33.             return -1 ;    
  34.         }
  35.      }
  36.         
  37.     if ( strcmp ( "-a" , argv[i] ) == 0 )
  38.     {
  39.         printf ("input ip address : %s \n", argv[i+1]) ;
  40.     
  41.         if ( inet_aton (argv[i+1] , &destAddr ) < 0 )
  42.         {
  43.             perror (" invalid ip address ") ;
  44.             return -1 ;
  45.         }
  46.     }
  47.     
  48.     if ( strcmp ( "-n" , argv[i] ) == 0 )
  49.     {
  50.         thread_num = atoi (argv[i+1]) ;
  51.     
  52.         if ( thread_num <= 0 )
  53.         {
  54.             perror (" invalid threadnum ") ;
  55.             return -1 ;    
  56.         }
  57.     }
  58.   }
  59.   
  60.   printf ("here is the info you input\n") ;
  61.   printf ("max port : %d \n" , max_port ) ;
  62.  // printf ("address ip : %s\n", inet_nota (destAddr) ) ;
  63.   printf ("thread number : %d \n" , thread_num) ;
  64.     
  65.  
  66.   myScanner = new Scanner (thread_num , destAddr , max_port ) ;    
  67.   myScanner->run () ;


  68.   goto success ;

  69.   error :
  70.     printf ("main error") ;
  71.     goto success ;
  72.  success:
  73.     return 0 ;
  74. }



程序运行顺序:
1. 首先在一个 terminal 中运行 ./server
2. 然后在新开启一个 terminal 输入命令
-m (你要扫描检测的端口的最大值 [0,65535]) -a (你要检查端口所在的主机 IP 以 xxx.xxx.xxx.xxx 的格式) -n (你要开启多少个线程并行检查端口)
例如
 -m 1027 -a 127.0.0.1 -n 100

end
阅读(1690) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~