- 论坛徽章:
- 0
|
- #include <pthread.h>
- #include <sys/epoll.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #define maxevents 200
- #define max_thread 6000
- #define MAXLINE 1024
- #define max_connect 5
- void *work(void *arg);
- void setnonblocking(int sock);
- void do_use_fd(struct epoll_event *events);
- pthread_mutex_t lock_mutex = PTHREAD_MUTEX_INITIALIZER;
- int lines = 0;
- int epollfd = 0;
- int main(){
- pthread_t pid_t;
- struct epoll_event ev, events[maxevents]={0};
- int nfds = 0;
- int n = 0;
- int status = 0;
- //lock_mutex = PTHREAD_MUTEX_INITIALIZER;
- status = pthread_create(&pid_t, NULL, work, NULL); // 起一个线称建立连接
- if (0 == status) {
- printf(" pthread created \n");
- } else {
- perror(" pthread create fail\n");
- return 0;
- }
- epollfd = epoll_create(maxevents); // 建立epoll
- if (-1 == epollfd){
- perror("error cannot epoll_create\n");
- return 0;
- } else {
- printf("epollfd = %d \n", epollfd);
- }
- printf(" begin epoll_wait \n");
- for (;;) {
- //printf("befor epoll_wait %d \n", &(events[0]));
- nfds = epoll_wait(epollfd, events, maxevents, 500); // 开始抓回复
- printf(" after epoll_wait nfds = %d\n", nfds);
- if(nfds == -1){
- perror("nfds == -1 ");
- return 0;
- }else {
- printf("nfds = %d \n", nfds);
- }
- for(n = 0; n < nfds; ++n) {
- do_use_fd(&(events[n]));
- } // end for
- } // end for
- return 0;
- }
- void *work(void *arg){ // 这个就是工作线称主要发起连接
- int i = 0 ;
- int create_conn = 1;
- struct sockaddr_in clientadd;
- int client;
- struct epoll_event ev;
- int len = 0;
- pthread_detach(pthread_self()); // this
- for (;;){
- create_conn = 1;
- pthread_mutex_lock(&lock_mutex);
- if (lines > max_connect){
- create_conn = 0;
- }
- pthread_mutex_unlock(&lock_mutex);
- if (0 == create_conn){
- sleep(1);
- continue;
- }
- // else
- client = socket(AF_INET , SOCK_STREAM, 0);
- if (client < 0){
- sleep(1);
- continue;
- }
- printf("begin memset \n");
- memset(&clientadd, 0, sizeof(clientadd));
- clientadd.sin_family = AF_INET;
- clientadd.sin_addr.s_addr = inet_addr("192.168.1.150");
- clientadd.sin_port = htons(80);
- setnonblocking(client);
- ev.events = EPOLLOUT;
- ev.data.fd = client;
- if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client, &ev) < 0) {
- printf(" fd = %d ", client);
- perror("epoll set insertion error");
- return NULL;
- } else {
- printf(" add to %d epoll pool\n", epollfd);
- }
- printf("begin connect \n");
- connect(client, (struct sockaddr*)&clientadd, sizeof(clientadd));
- printf("begin connect \n");
- pthread_mutex_lock(&lock_mutex);
- ++lines;
- printf(" now lines = %d \n", lines);
- pthread_mutex_unlock(&lock_mutex);
- } // end for
- }
- void setnonblocking(int sock){
- int opts;
- opts=fcntl(sock,F_GETFL);
- if(opts<0)
- {
- perror("fcntl(sock,GETFL)");
- exit(1);
- }
- opts = opts|O_NONBLOCK;
- if(fcntl(sock,F_SETFL,opts)<0)
- {
- perror("fcntl(sock,SETFL,opts)");
- exit(1);
- }
- }
- void do_use_fd(struct epoll_event *events){
- struct epoll_event ev;
- int n = 0;
- char buff[100] ="get / http/1.1\r\n\r\n";
- char inbuff[MAXLINE] ={0};
- int client = events->data.fd;
- int closeit = 1;
- printf(" in do user fd \n");
- if (events->events & EPOLLIN){ // 可以读了
- if ( (client = events->data.fd) < 0) return;
- while (1) {
- if ( (n = read(client, inbuff, MAXLINE)) < 0) {
- if (errno == ECONNRESET) {
- printf("readline error errno == ECONNRESET\n");
- break;
- } else {
- printf("readline error no data \n");
- closeit = 0;
- break;
- }
- } else if (n == 0) {
- printf("readline == 0 \n");
- break;
- } else {
- printf("i get %d byte form %d \n", n ,client);
- }
- } // end while (1)
- if (1 == closeit) {
- printf("close socket %d now \n", client);
- close(client);
- ev.events = EPOLLIN |EPOLLERR;
- ev.data.fd = client;
- epoll_ctl(epollfd, EPOLL_CTL_DEL, client, &ev);
-
- pthread_mutex_lock(&lock_mutex);
- --lines;
- printf(" now lines = %d \n", lines);
- pthread_mutex_unlock(&lock_mutex);
- return;
- }
- } else if (events->events & EPOLLOUT) // end if
- {
- if ( (client = events->data.fd) < 0) return;
- printf(" now write %d \n",events->data.fd);
- n = write(events->data.fd, buff, strlen(buff));
- printf("%d write = %d \n", lines, n);
- ev.events = EPOLLIN |EPOLLERR;
- ev.data.fd = client;
- epoll_ctl(epollfd, EPOLL_CTL_MOD, client, &ev);
- return;
- }
- //close(events->data.fd); //读完了 就短掉连接
- }
复制代码
本意是一个网络爬虫,不断去不同的服务器获取网页。 采用epoll 而不是多线称+简单的代码。
因为是爬虫 所以需要不断的发起连接。 这个连接可以在 epoll_wait 里面建立也可以起一个线程,在线程里面建立
我采用了后者。
目前的问题是, 只能运行一次。 当一条连结,建立,完成后,断开。 再次建立第二个连接 当使用的是上次被关闭的那个fd
程序就死了
help |
|