首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

小弟我在linux下写了个简单的多线程端口扫描程序,运行时出现有关问题,请问一下

2012-02-25 
我在linux下写了个简单的多线程端口扫描程序,运行时出现问题,请教一下!#includestdio.h#includestdlib.

我在linux下写了个简单的多线程端口扫描程序,运行时出现问题,请教一下!
#include   <stdio.h>
#include   <stdlib.h>
#include   <errno.h>
#include   <pthread.h>
#include   <sys/types.h>
#include   <sys/socket.h>
#include   <sys/file.h>
#include   <netinet/in.h>


struct   sockaddr_in   servaddr;
int   g_nThreadNum,   g_nMaxThread;
long   g_nNowPort;
char   *host;
struct   timeval   timeout;


static   void*   thread_scan_port(void   *pPort)
{
int   sockfd,   flags,   error,nPort,   retconn,   retval,   len;
fd_set   wfds;


    pthread_detach(pthread_self());
   
    nPort   =   *(int   *)pPort;        


//printf( "nPort   =   %d\n ",   nPort);

sockfd   =   socket(AF_INET,   SOCK_STREAM,   0);
if   (sockfd   <   0)
  {
  perror( "\nsocket ");
  g_nThreadNum--;
  return(NULL);
  }

  /*   设为非阻塞方式   */
  if   ((flags   =   fcntl(sockfd,   F_GETFL,   0))   <   0)
  {
  perror( "\nfcntl: ");
  g_nThreadNum--;
  return(NULL);
  }
if   (fcntl(sockfd,   F_SETFL,   flags   |   O_NONBLOCK)   <   0)
{
perror( "\nfcntl: ");
g_nThreadNum--;
return(NULL);
}

bzero(&servaddr,   sizeof(servaddr));
servaddr.sin_family   =   AF_INET;
servaddr.sin_port   =   htons(nPort);
servaddr.sin_addr.s_addr   =   inet_addr(host);


if   ((retconn   =   connect(sockfd,   (struct   sockaddr*)&servaddr,   sizeof(servaddr)))   <   0)
if   (EINPROGRESS   !=   errno)
{
g_nThreadNum--;
return(NULL);
}

FD_ZERO(&wfds);
FD_SET(sockfd,   &wfds);

retval   =   select(sockfd+1,   NULL,   &wfds,   NULL,   &timeout);
if   (0   ==   retval   ||   -1   ==   retval)/*   超时或者select错误   */
{
//printf( "port   connect   is   fail!\n ");
close(sockfd);
            g_nThreadNum--;
            return(NULL);

}

if   (FD_ISSET(sockfd,   &wfds))/*   sockfd可写   */  
{
len   =   sizeof(error);
if   (getsockopt(sockfd,   SOL_SOCKET,   SO_ERROR,   &error,   &len)   <   0)
{
g_nThreadNum--;
return(NULL);
}
}
else
{
perror( "\nFD_ISSET: ");
g_nThreadNum--;
return(NULL);
}

if   (error)   /*   链接时有错误发生   */
{
close(sockfd);
g_nThreadNum--;
return(NULL);
}
else/*   链接成功返回0   */
{
printf( "port   %d   is   opened!\n ",   nPort);
g_nThreadNum--;
return(NULL);

}


}

/*   等待所有线程结束   */
void   WaitThreadEnd(void)
{


usleep(1000);
printf( "\nThread   ending....\n ");
while(g_nThreadNum> 0)
{
usleep(1);
printf( "   =|=\t%d   threads   \r ",g_nThreadNum);
}
printf( "threadnum   =   %d ",   g_nThreadNum);

printf( "\nThread   ended!\n ");
}


int   main(int   argc,   char   **argv)
{
int   i,   j,   nStartPort,   nEndPort,nThread,   ret,   index;
int   nPort[1000];
pthread_t   tid;

/*   当前的线程数量   */
g_nThreadNum   =   0;
host   =   argv[1];
nThread   =   atoi(argv[3]);
sscanf(argv[2],   "%d-%d ",   &nStartPort,   &nEndPort);

printf( "nStartPort   =   %d\n ",   nStartPort);
printf( "nEndPort   =   %d\n ",   nEndPort);

/*   最大线程数   */
g_nMaxThread   =   (nThread   > =   1000)?   1000   :   nThread;


timeout.tv_usec   =   0;
if   (g_nMaxThread   >   500)
timeout.tv_sec   =   2;
else
timeout.tv_sec   =   1;

printf( "MaxThread   =   %d\n ",   g_nMaxThread);
printf( "ThreadNum   =   %d\n ",   g_nThreadNum);

index   =   0;
for   (i   =   nStartPort;   i   <=   nEndPort;   i++,   index++)
nPort[index]   =   i;

for   (j   =   0;   j   <   index;   j++)
{

g_nThreadNum++;
/*   若超过最大的线程数,程序休眠等待线程的释放   */
while   (g_nThreadNum   > =   g_nMaxThread)
{
usleep(10);
}

ret   =   pthread_create(&tid,   NULL,   (void   *)thread_scan_port,   &nPort[j]);
if   (0   !=   ret)
{
perror( "\npthread_create ");
exit(1);
}
}

//printf( "ThreadNum   =   %d\n ",   g_nThreadNum);
WaitThreadEnd();  

return   0;

}


编译:   gcc   -lpthread   PortScanner.c   -o   PortScanner
运行:./PortScanner   192.168.2.1   1-1000   500
注:192.168.2.1   要扫描的地址   1-1000   端口范围   500   指定可以产生的最大线程数

当端口和线程比较大时运行就出问题了


[解决办法]
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <pthread.h>
#include <thread_db.h>
#include <arpa/inet.h>

#define MAX_PORT 4000
#define MAX_THREAD 100
/* basename(argv[0]). netBSD,linux and gnu libc all define it. */
extern char *__progname;

/* globals */
int port_num,thread_num=100;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main(int argc,char **argv)
{
void *thread_main(void *);
pthread_t tid;

#ifndef HAVE__PROGNAME
__progname = argv[0];
#endif
printf( "----kf_701 scan tool--------- ");



if(argc != 2){
fprintf(stderr, "* Usage: %s host ",__progname);
exit(0);
}

/* create threads */
int i;
for(i=0;i <MAX_THREAD;i++)
pthread_create(&tid,NULL,&thread_main,argv[1]);
/* main pause */
for( ; ; )
pause();
}

void *thread_main(void *arg)
{
struct sockaddr_in sa;
struct hostent *host;
int i,sockfd;

pthread_detach(pthread_self());

/* init sockaddr_in struct */
bzero(&sa,sizeof(struct sockaddr));
sa.sin_family = AF_INET;
if(inet_aton((char *)arg,&sa.sin_addr) == 0){
host = gethostbyname((char *)arg);
if(host == NULL){
fprintf(stderr, "Hostname Error: %s ",hstrerror(h_errno));
exit(1);
}
sa.sin_addr = *(struct in_addr *)(host-> h_addr_list[0]);
}

while(1){
/* get a port number */
if(pthread_mutex_lock(&mutex) != 0) exit(1);
if(++port_num > MAX_PORT){
if(pthread_mutex_unlock(&mutex) != 0) exit(1);
if(--thread_num == 0){
printf( "----------------------------- ");
exit(0);
}
pthread_exit(NULL);
}
i=port_num;
if(pthread_mutex_unlock(&mutex) != 0) exit(1);
/* try to connect */
sa.sin_port=htons(i);
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
perror( "Create socket error "),exit(1);
if(connect(sockfd,(struct sockaddr *)&sa,sizeof(sa)) == 0)
printf( "* port %d is open ",i);
if(close(sockfd) < 0)
perror( "shutdown error "),exit(1);
}/*end while*/
}

热点排行
Bad Request.