Chinaunix首页 | 论坛 | 博客
  • 博客访问: 594049
  • 博文数量: 92
  • 博客积分: 5026
  • 博客等级: 大校
  • 技术积分: 1321
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-28 11:04
文章分类

全部博文(92)

文章存档

2011年(9)

2010年(17)

2009年(12)

2008年(54)

我的朋友

分类: LINUX

2008-07-19 22:54:28

/*
   多线程最终版。基本的参考前两篇文章
   g++ scan.c -lpthread -o scan
   ./scan -s1 -e254 -t5 -p1234 -n10
*/
 
 
 
 
/*
   MyQueue.h
*/
 
#ifndef _H_MYQUEUE_
#define _H_MYQUEUE_
 
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
        int data;
 
struct Elem {
        int data;
        Elem* next;
};
 
class MyQueue {
public:
        MyQueue() {
                size_ = 0;
                head_ = tail_ = 0;
        }
        int enqueue(int value) {
                Elem* elem = new Elem();
                elem->data = value;
                elem->next = 0;
                if(size_ == 0) {
                        head_ = tail_ = elem;
                } else {
                        tail_->next = elem;
                        tail_ = elem;
                }
                size_++;
//              printf("enqueue data:%d\t\tsize:%d\n ", value, size_);
                return 0;
        }
        int dequeue(int *value) {
                if(size_ < 1)return -1;
                *value = head_->data;
                head_ = head_->next;
                if(size_ == 1)tail_ = 0;
                size_--;
//              printf("dequeue data:%d\t\tsize:%d\n", *value, size_);
                return 0;
        }
        int size() {
                return size_;
        }
private:
        int size_;
        Elem *head_;
        Elem *tail_;
};
 
 
#endif
 
 
 
 
/*
 
        scan.c
 
*/
 
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
 
#include "unistd.h"
#include "sys/types.h"
#include "sys/time.h"
#include "sys/socket.h"
#include "arpa/inet.h"
#include "netinet/in.h"
#include "netdb.h"
#include "fcntl.h"
#include "errno.h"
#include "pthread.h"
#include "semaphore.h" //posix
 
 
#include "MyQueue.h"
#include "MyQueue.h"
 
 
sem_t sem;
sem_t mutex;
 
MyQueue queue;
 
int start_ip = 1;
int end_ip = 254;
int time_connect = 10;
int port = 8888;
int nthreads = 255;
 
void* work(void* arg) {
        struct timeval timeout;
        fd_set wset;
        fd_set rset;
        char straddr[100];
        pthread_detach(pthread_self());
//      printf("%d\tthread started...\n", pthread_self());
        for(;;) {
                sem_wait(&sem);
//              printf("%d\t work\n", pthread_self());
                int value;
                if(queue.dequeue(&value) == -1)continue;
 
                int sockfd = socket(AF_INET, SOCK_STREAM, 0);
                if(sockfd == -1)perror("socket()");
 
                sprintf(straddr, "192.168.1.%d\0", value);
//              fprintf(stderr, "scan %s\t", straddr);
 
                struct sockaddr_in server_addr;
                server_addr.sin_family = AF_INET;
                if(inet_pton(AF_INET, straddr, &(server_addr.sin_addr)) != 1)perror("inet_pton()");
                server_addr.sin_port = htons(port);
 
                int flags;
                if((flags = fcntl(sockfd, F_GETFL, 0)) < 0)perror("fcntl()");
                if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)< 0)perror("fcntl()");
                int result = connect(sockfd, (struct sockaddr*)(&server_addr), sizeof(server_addr));
                if(result == -1) {
                        if(errno == EINPROGRESS) {
                                timeout.tv_sec  = 10;
                                timeout.tv_usec = 0;
                                if(time_connect >= 100) {
                                        timeout.tv_sec  = 0;
                                        timeout.tv_usec = time_connect;
                                } else if(time_connect > 0) {
                                        timeout.tv_sec  = time_connect;
                                        timeout.tv_usec = 0;
                                }
                                FD_ZERO(&wset);
                                FD_SET(sockfd, &wset);
                                rset = wset;
                                int n = select(sockfd+1, &rset, &wset, 0, &timeout);
                                if(n == -1 && errno!= EINTR) {
                                        fprintf(stderr, "ERROR:\tselect() %s(%d)\n", strerror(errno), errno);
                                } else if(n > 0) {
 
                                        int optval;
                                        int optlen = 4;
                                        if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&optval, (socklen_t*)&optlen) < 0)perror("getsockopt()");
                                        if(optval == 0) {
                                                fprintf(stderr, "SUCCESS:\tconnect %s:%d\n", straddr, port);
                                        } else {
                                                fprintf(stderr, "ERROR:\tconnect %s:%d\terror:%s(%d)\n",straddr, port, strerror(optval), optval);
                                        }
                                } else if(n == 0) {
                                        fprintf(stderr, "ERROR:\tconnect %s:%d timeout\n",straddr, port);
                                }
                        } else {
                                close(sockfd);
                                fprintf(stderr, "ERROR(directly):\tconnect %s:%d\terror:%s(%d)\n",straddr, port, strerror(errno), errno);
                        }
                } else {
                        fprintf(stderr, "SUCCESS(directly):\tconnect %s:%d\n", straddr, port);
                        close(sockfd);
                        continue;
                }
                close(sockfd);
                break;
 
        }
//      printf("%d exit\n", pthread_self());
        pthread_exit(NULL);
        return 0;
}
void usage() {
        printf("use format:\n\t-s startip\n\t-e endip\n\t-t connect_timeout\n\t-p port\n");
        exit(-1);
}
 
 
int main(int argc, char** argv) {
 
        sem_init(&sem, 0, 0);
        sem_init(&mutex, 0, 1);
 
        int opt;
        while((opt = getopt(argc, argv, "s:e:t:p:n:")) != -1) {
                switch(opt) {
                        case 's':start_ip = atoi(optarg);break;
                        case 'e':end_ip   = atoi(optarg);break;
                        case 't':time_connect = atoi(optarg);break;
                        case 'p':port = atoi(optarg);break;
                        case 'n':nthreads = atoi(optarg);break;
                        case '?':usage();
                }
        }
 
        if(nthreads <= 1)nthreads = 1;
        int toscan = end_ip-start_ip+1;
        if(nthreads > toscan)nthreads = toscan;
 
        printf("-----------------------------------------------------------------------------------------------------\n");
        printf("\t scan will use[%d]threads 192.168.1.%d -> 192.168.1.%d with connect timeout %d at port %d \n", nthreads, start_ip, end_ip, time_connect, port);
        printf("-----------------------------------------------------------------------------------------------------\n");
 
        for(int i=0; i                pthread_t tid;
                pthread_create(&tid,  0, work, 0);
        }
 
 
        printf("ready to scan..\n");
        for(int i=start_ip; i 
                queue.enqueue(i);
                sem_post(&sem);
 
        }
        pthread_exit(NULL);   //wait all threads exit
        printf("main exit...\n");
        return 0;
 
}
阅读(1687) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~