亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? epoll_td2.cc

?? 介紹epoll
?? CC
字號:
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>

#define MAXLINE    10
#define OPEN_MAX   100
#define LISTENQ    20
#define SERV_PORT  5555
#define INFTIM     1000

#define MAXFDS    16 * 10000
#define EVENTSIZE 15 * 10000

// 線程池任務隊列結構體
struct task
{
	int fd;            // 需要讀寫的文件描述符
	struct task *next; // 下一個任務
};

// 用于讀寫兩個的兩個方面傳遞參數
struct user_data
{
	int fd;
	unsigned int n_size;
	char line[MAXLINE];
};

// 線程的任務函數
void *readtask(void *args);
void *writetask(void *args);


// 聲明epoll_event結構體的變量,ev用于注冊事件,數組用于回傳要處理的事件
struct epoll_event ev, events[EVENTSIZE];
int epfd;
pthread_mutex_t mutex;
pthread_cond_t  cond1;
struct task *readhead=NULL,*readtail=NULL,*writehead=NULL;

// 設置非阻塞模式
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);
	}    
}

// 發送數據
ssize_t socket_send(int sockfd, const char *buffer, size_t buflen)
{
	ssize_t tmp;
	size_t total  = buflen;
	const char *p = buffer;

	for( ; ; )
	{
		tmp = send(sockfd, p, total, 0);
		if(tmp < 0)
		{
			// 當send收到信號時,可以繼續寫,但這里返回-1.
			if(errno == EINTR)
			{
				return -1;
			}

			// 當socket是非阻塞時,如返回此錯誤,表示寫緩沖隊列已滿,
			// 在這里做延時后再重試.
			if(errno == EAGAIN)
			{
				usleep(1000);
				continue;
			}

			return -1;
		}

		if((size_t)tmp == total)
		{
			return buflen;
		}

		total -= tmp;
		p += tmp;
	}

	return tmp;
}

// 接收數據
ssize_t socket_recv(int sockfd, char *buffer, size_t buflen)
{
	int rs, n;

	while(rs)
	{
		n = recv(sockfd, buffer, MAXLINE, 0);
		if(n < 0)
		{
			// 由于是非阻塞的模式,所以當errno為EAGAIN時,表示當前緩沖區已無數據可讀
			// 在這里就當作是該次事件已處理處.
			if(errno == EAGAIN)
			{
				break;
			}
			else
			{
				return -1;
			}
		}
		else if(n == 0)
		{
			// 這里表示對端的socket已正常關閉.
			close(sockfd);
		}

		if(n == sizeof(buffer))
		{
			rs = 1;   // 未讀完 需要再次讀取
		}
		else
		{
			rs = 0;
		}
	}

	return n;
}
int main(int argc, char *argv[])
{
	int i, maxi, listenfd, connfd, sockfd,nfds;
	int opt = 1;
	pthread_t tid1,tid2;
	struct task *new_task=NULL;
	struct user_data *rdata=NULL;
	socklen_t clilen;

	pthread_mutex_init(&mutex,NULL);
	pthread_cond_init(&cond1,NULL);

	// 初始化用于讀線程池的線程
	pthread_create(&tid1, NULL, readtask, NULL);
	pthread_create(&tid2, NULL, readtask, NULL);

	// 生成用于處理accept的epoll專用的文件描述符    
	epfd = epoll_create(MAXFDS);

	struct sockaddr_in clientaddr;
	struct sockaddr_in serveraddr;
	listenfd = socket(AF_INET, SOCK_STREAM, 0);

	// 重復綁定
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));

	// 把socket設置為非阻塞方式
	setnonblocking(listenfd);

	// 設置與要處理的事件相關的文件描述符
	ev.data.fd = listenfd;
	//設置要處理的事件類型
	ev.events = EPOLLIN | EPOLLET;//EPOLLIN | EPOLLERR | EPOLLHUP;

	// 注冊epoll事件
	epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd,&ev);

	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;

	//char *local_addr="192.168.100.5";
	//inet_aton(local_addr,&(serveraddr.sin_addr));
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serveraddr.sin_port        = htons(SERV_PORT);
	bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
	listen(listenfd, LISTENQ);

	maxi = 0; 
	for ( ; ; ) 
	{
		// 等待epoll事件的發生
		nfds = epoll_wait(epfd, events, EVENTSIZE, -1);

		// 處理所發生的所有事件      
		for(i = 0; i < nfds; ++i)
		{
			if(events[i].data.fd == listenfd)// 客戶端;連接事件
			{
				connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
				if(connfd < 0)
				{
					perror("connfd < 0");
					exit(1);
				}

				setnonblocking(connfd);

				unsigned char *sip = (unsigned char *)&clientaddr.sin_addr.s_addr;
				printf("%d connect from >> %d.%d.%d.%d\n", connfd, sip[0], sip[1], sip[2], sip[3]);

				// 設置用于讀操作的文件描述符
				ev.data.fd = connfd;
				// 設置用于注測的讀操作事件
				ev.events = EPOLLIN | EPOLLET;
				//注冊ev
				epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
			}
			else if(events[i].events & EPOLLIN)// 有讀數據
			{
				printf("reading!\n");                 
				if ( (sockfd = events[i].data.fd) < 0)
				{
					continue;
				}
				new_task = new task();
				new_task->fd = sockfd;
				new_task->next = NULL;

				// 添加新的讀任務
				pthread_mutex_lock(&mutex);
				if(readhead==NULL)
				{
					readhead = new_task;
					readtail = new_task;
				}    
				else
				{    
					readtail->next = new_task;
					readtail = new_task;
				}    

				// 喚醒所有等待cond1條件的線程
				pthread_cond_broadcast(&cond1);
				pthread_mutex_unlock(&mutex);  
			}
			else if(events[i].events & EPOLLOUT)// 有寫數據
			{    
				rdata = (struct user_data *)events[i].data.ptr;
				sockfd = rdata->fd;
				write(sockfd, rdata->line, rdata->n_size);

				delete rdata;

				// 設置用于讀操作的文件描述符
				ev.data.fd = sockfd;
				// 設置用于注測的讀操作事件
				ev.events = EPOLLIN | EPOLLET;
				// 修改sockfd上要處理的事件為EPOLIN
				epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
			}
			else if(events[i].events & EPOLLHUP)
			{
				// 斷開的情況,刪除事件,然后關閉fd

				rdata = (struct user_data *)events[i].data.ptr;
				sockfd = rdata->fd;

				// 設置用于讀操作的文件描述符
				ev.data.fd = sockfd;
				ev.events  = 0;
				epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);

				//struct epoll_event event;  				//event.events   = 0; 				//event.data.u64 = 0; 				//event.data.ptr = sockfd; 				//epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &event);  

				printf("epollhup %d\n", sockfd);
				close(sockfd);
			}
		}
	}
}

void *readtask(void *args)
{
	int fd = -1;
	unsigned int n;

	//用于把讀出來的數據傳遞出去
	struct user_data *data = NULL;
	for( ; ; )
	{
		pthread_mutex_lock(&mutex);

		//等待到任務隊列不為空
		while(readhead == NULL)
		{
			pthread_cond_wait(&cond1, &mutex);
		}

		fd = readhead->fd;

		// 從任務隊列取出一個讀任務
		struct task *tmp = readhead;

		readhead = readhead->next;
		delete tmp;

		pthread_mutex_unlock(&mutex);
		data = new user_data();
		data->fd = fd;
		if ((n = read(fd, data->line, MAXLINE)) < 0) 
		{
			if (errno == ECONNRESET) 
			{
				std::cout<<"errno == ECONNRESET "<<fd<<std::endl;
				close(fd);
			} 
			else
			{
				std::cout<<"readline error "<<fd<<std::endl;
			}

			if(data!=NULL)
			{
				delete data;
			}
		} 
		else if (n == 0) 
		{
			printf("%d Client close connect!\n", fd);

			close(fd);

			if(data != NULL)
			{
				delete data;
			}
		}
		else
		{
			// 通知寫事件
			data->n_size = n;

			//設置需要傳遞出去的數據
			ev.data.ptr = data;
			//設置用于注測的寫操作事件
			ev.events = EPOLLOUT | EPOLLET;
			//修改sockfd上要處理的事件為EPOLLOUT
			epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);
		}
	}
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
激情综合网激情| 亚洲精品国产无套在线观| 91看片淫黄大片一级在线观看| 亚洲成人www| 亚洲乱码中文字幕| 亚洲欧洲三级电影| 国产肉丝袜一区二区| 精品国产精品一区二区夜夜嗨| 欧美日韩综合不卡| 欧美午夜片在线观看| 91成人在线观看喷潮| 色88888久久久久久影院按摩| eeuss国产一区二区三区| 成人性生交大片免费看中文| 成人免费毛片aaaaa**| 国产精品一区二区在线播放| 久久99热99| 国内精品视频一区二区三区八戒 | 欧美日韩成人一区二区| 色天天综合久久久久综合片| 色婷婷av一区二区三区大白胸 | 国产精品久久毛片av大全日韩| 亚洲精品在线观看网站| 久久影院午夜片一区| 久久影院午夜片一区| 国产精品私房写真福利视频| 国产精品毛片高清在线完整版| 国产精品欧美极品| 亚洲天堂成人在线观看| 亚洲已满18点击进入久久| 亚洲午夜精品网| 日韩国产精品久久久| 狠狠色丁香久久婷婷综| 菠萝蜜视频在线观看一区| 色婷婷精品久久二区二区蜜臀av | 91精品欧美久久久久久动漫| 精品国产亚洲一区二区三区在线观看| 日韩视频免费观看高清完整版| 精品少妇一区二区三区在线播放| xf在线a精品一区二区视频网站| 国产午夜精品一区二区三区嫩草 | 久久久综合视频| 国产精品久久久久影院老司| 一区2区3区在线看| 奇米在线7777在线精品| 国产成人av资源| 在线中文字幕一区| 久久先锋影音av| 亚洲欧美日韩国产综合| 久久国内精品自在自线400部| 国产精品亚洲视频| 欧美日韩一区二区三区高清| 久久久不卡网国产精品一区| 洋洋av久久久久久久一区| 极品少妇xxxx偷拍精品少妇| 99re热视频精品| 日韩欧美高清dvd碟片| 一区二区三区中文在线观看| 久久99精品久久久久久久久久久久| 成人一级片在线观看| 欧美一区二区美女| 亚洲激情av在线| 国产在线播精品第三| 欧美剧情电影在线观看完整版免费励志电影| 2014亚洲片线观看视频免费| 午夜婷婷国产麻豆精品| 99国产一区二区三精品乱码| 久久久久久久网| 日本不卡在线视频| 在线欧美日韩国产| 中文字幕一区二区三中文字幕| 看电影不卡的网站| 91精品国产一区二区| 曰韩精品一区二区| k8久久久一区二区三区| 国产欧美精品一区二区三区四区| 免费高清不卡av| 欧美在线你懂得| 亚洲私人影院在线观看| 成人h动漫精品| 久久久久久久综合| 韩国三级在线一区| 欧美不卡视频一区| 蜜臀av一区二区在线免费观看| 欧美日韩黄视频| 亚洲午夜国产一区99re久久| 色综合天天综合网天天狠天天| 中文字幕乱码一区二区免费| 国产经典欧美精品| 久久综合久久鬼色| 国产精品一区二区久激情瑜伽| 久久综合久久综合久久综合| 国产尤物一区二区| 久久久久久久综合日本| 高清在线不卡av| 国产精品无人区| 成人午夜在线播放| 亚洲色图都市小说| 日本韩国欧美三级| 亚洲一区自拍偷拍| 欧美精品第一页| 蜜芽一区二区三区| 久久久久久久久久久久久女国产乱| 蜜臀av一区二区三区| 久久五月婷婷丁香社区| 成人午夜av在线| 亚洲日本在线a| 欧美久久一区二区| 国产黑丝在线一区二区三区| 国产精品国产三级国产普通话99| 色域天天综合网| 午夜国产不卡在线观看视频| 欧美大黄免费观看| www.亚洲在线| 婷婷成人综合网| 久久―日本道色综合久久| 不卡的电影网站| 亚洲成av人影院| 久久综合国产精品| 91福利小视频| 久久爱www久久做| 国产精品国产三级国产aⅴ原创| 欧美亚洲日本一区| 国产福利视频一区二区三区| 亚洲情趣在线观看| 精品欧美一区二区久久| 91污在线观看| 青青草国产成人99久久| 国产精品理论片| 日韩一区二区三区观看| 91一区二区三区在线观看| 开心九九激情九九欧美日韩精美视频电影| 中文字幕不卡三区| 国产日韩欧美制服另类| 在线观看日韩精品| 风间由美一区二区三区在线观看 | 一本色道**综合亚洲精品蜜桃冫| 亚瑟在线精品视频| 国产欧美一区二区精品婷婷| 欧美日韩视频第一区| 国产传媒日韩欧美成人| 午夜激情一区二区三区| 自拍偷拍国产精品| 久久精品日产第一区二区三区高清版| 色狠狠综合天天综合综合| 国产精品一区二区黑丝| 五月综合激情网| 亚洲免费在线播放| 国产精品久久久久久久午夜片| 日韩精品一区二区三区蜜臀| 欧美日韩国产综合草草| av高清久久久| 精品一区二区三区影院在线午夜| 一区二区三区在线看| 欧美激情综合五月色丁香| 精品少妇一区二区三区视频免付费| 91福利在线导航| proumb性欧美在线观看| 国产精品伊人色| 久久国产成人午夜av影院| 午夜a成v人精品| 亚洲国产精品久久久久婷婷884| 1000精品久久久久久久久| 国产精品天干天干在观线| 久久精品欧美日韩| 久久综合九色综合欧美亚洲| 日韩欧美国产一区二区三区| 欧美一区二区三区免费| 欧美精品一级二级三级| 在线不卡一区二区| 7777精品伊人久久久大香线蕉的| 欧美三级资源在线| 欧美日韩高清影院| 欧美日韩aaaaaa| 欧美色图在线观看| 欧美一区二区视频网站| 欧美精品一区二区三区久久久| 日韩美女视频一区二区在线观看| 日韩免费视频一区| 久久久久综合网| 中文字幕在线不卡一区二区三区| 1000部国产精品成人观看| 亚洲综合精品自拍| 美女一区二区视频| 韩国精品主播一区二区在线观看 | 国模冰冰炮一区二区| 国产精品一区免费视频| 波多野结衣精品在线| 色菇凉天天综合网| 日韩一卡二卡三卡四卡| 欧美激情中文字幕一区二区| 亚洲裸体在线观看| 日韩不卡一区二区三区| 国产精品一区二区三区乱码| 99久久国产综合色|国产精品| 欧美视频一区二区三区四区 | 亚洲国产欧美另类丝袜| 麻豆专区一区二区三区四区五区| 国产成人亚洲综合a∨猫咪| 成人激情文学综合网|