我想用C实现一个多线程的端口扫描,对每个ip都创建100个线程;
在main里for循环中创建线程,打印出来的参数(arg->min_port,arg->max_port)是没问题的,
但是在线程函数里打印出传进去的参数时,min_port与max_port都是一样的,请问该怎么解决? 谢谢
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#define THREAD_NUM 100
#define MAX_PORT 65535
#define SEG_LEN 649
struct port_seg
{
char *dest;
int min_port;
int max_port;
};
typedef struct port_seg port_segment;
void * scan(void * arg)
{
struct port_seg * parg;
int min_port;
int max_port;
int sockfd;
struct sockaddr_in server;
int length;
int ret;
struct servent* result;
parg = (struct port_seg *)arg;
min_port = parg->min_port;
max_port = parg->max_port;
printf("ip:%s\n",parg->dest);
printf("min_port:%d\n",min_port);
printf("max:%d\n",max_port);
if (-1==(sockfd=socket(AF_INET,SOCK_STREAM,0)))
{
perror("generating socket error\n");
exit(1);
}
memset(&server,0,sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(parg->dest);
length = sizeof(struct sockaddr);
for(int i=min_port;i<=max_port;i++)
{
server.sin_port = htons(i);
if(0>(ret=connect(sockfd,(struct aockaddr*)&server,length)))
{
//perror("connect err\n");
continue;
}
else
{
if(NULL == (result = getservbyport(server.sin_port,"tcp")))
{
continue;
}
else
{
printf(">>> ip:%s, name:%s, s_port:%d\n", parg->dest, result->s_name,ntohs(result->s_port));
}
}
close(sockfd);
}
close(sockfd);
exit(0);
}
int main(int argc, char** argv)
{
pthread_t * thread;
thread = (pthread_t *)malloc(THREAD_NUM * sizeof(pthread_t));
if(argc<1)
{
printf("./portscanner ip1, ip2, ……");
exit(1);
}
for(int i=1; i<argc; i++)
{ // each group
for(int j=0;j<THREAD_NUM;j++)
{
// printf("j:%d ",j);
port_segment port;
port.dest = argv[i];
port.min_port = j*SEG_LEN+1;
if(j == THREAD_NUM - 1)
{
port.max_port = MAX_PORT;
}
else
{
port.max_port = port.min_port + SEG_LEN -1;
}
// printf("min:%d\n",port.min_port);
// printf("max:%d\n",port.max_port);
if ( pthread_create(&thread[j], NULL, scan, (void *)&port) != 0 )
{
perror( "pthread_create failed\n" );
free(thread);
exit(1);
}
}
}
exit(0);
}
你在创建线程后传进的参数,在没有进入下一次for循环给port.min 和port.max 赋值之前,scan线程中的parg->min 和 parg->max 值没有错。
创建了线程你要考虑到 这时候主线程不会停啊,还会继续跑的,主线程的for循环是会一直继续直到结束,一直在改变port地址里面的数据!
这判断的基础是在port的地址一直不变的情况下,建议打印一下port的地址看看!不要只打印数据!
main中定义的这个port是局部变量,把这个局部变量的地址传入线程是有问题的,因为线程函数在使用这个地址强转对象的时候,
外部这个局部变量可能就已经被销毁了;
这里应该new一个对象,然后传给线程,然后在线程函数退出的时候释放这个对象;或者使用智能指针,让它自动释放。