/*
多线程最终版。基本的参考前两篇文章
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;
}
阅读(1675) | 评论(0) | 转发(0) |