`
sunzixun
  • 浏览: 74871 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

<Nginx> epoll

阅读更多

之后会把nginx使用的简单epoll skeleton  总结一下

 

 

 

 // epoll检测到 EPOLLIN 调用之前注册的 ngx_connection_t r结构体指针

1:         ngx_epoll_module.c :            rev->handler(rev);

 

//开始处理http请求

2:          ngx_http_request.c:           

                                                          ngx_http_process_request_headers(r)

                                                          ngx_http_process_request_line(r)

                                                          ngx_http_process_request(r)

//开始真正的http 处理程序

3:         ngx_http_core_module.c:     ngx_http_handler(r)

 

 

4:         ngx_http_core_module.c:      ngx_http_core_run_phases(r);

 

//好戏开始了,这里开始打包http头部

 

 5:        ngx_http_static_module.c:    ngx_http_send_header(r)

 

//经过一系列的过滤模块

 6:

ngx_http_chunked_filter_module.c:   ngx_http_next_header_filter(r)

ngx_http_header_filter_module.c:     ngx_http_write_filter(r)

 

//真正的发送

7:ngx_http_write_filter_module.c:     chain = c->send_chain(c, r->out, limit);

ngx_linux_sendfile_chain.c:                rc = writev(c->fd, header.elts, header.nelts);

 

 

 

相信到这里大家对nginx的http请求相应有了一个粗犷的认识 ..  他没有用EPOLLOUT 去等到缓冲变化 来send

 

 

下面是我写的一个基本功能demo epoll 的例子  和网上很多给的应该大不相同 ,因为那些好多都是漏洞百出 一压就死的

 

 

 

static ssize_t epoll_recv(sock_con_s *c)
{

	static jj=0;
	ssize_t n_b,n_head;  
	unsigned short len; 
	struct iovec iov[3];
	buf_head_s b_head;
	struct epoll_event un_use;
	
	if(c->sock_fd <= 0) return EXC_OK;
 int i = 0;
	
	while(1)    
	{

		if(c->recv_bytes == 0 && c->if_head == 0 ){
			/*recv buf head!*/
		
			iov[0].iov_base = b_head._head;
			iov[0].iov_len = 2;
			iov[1].iov_base = &b_head._len;
			iov[1].iov_len = sizeof(u_short);	
			iov[2].iov_base = b_head._context;
			iov[2].iov_len = 4;	
			
			memset(put_buf, 0x00, sizeof(put_buf));
			memset(&b_head,0x00,sizeof(b_head));

		
			n_head = readv(c->sock_fd, iov, 3);	
			if(n_head < 0){
				 if (errno == EAGAIN) return 0;
				 else {goto PEER_OVER;}
			}

			if((n_head != sizeof(buf_head_s)) || 
					(check_protocol(&b_head) != 0))
					goto PEER_OVER; 
			
			len = ntohs(b_head._len);
			c->total_bytes = len;
			c->if_head = 1;
						
			for( i = 0 ;i < 8 ;i++)
			printf(" %.2x",((char*)(&b_head))[i]);
			printf("%d\n",jj++);
		}
		
		n_b = recv(c->sock_fd, put_buf + c->recv_bytes, 
			c->total_bytes - c->recv_bytes, 0);

		if(n_b < 0 ){

			switch(errno)
			{
				case EAGAIN:
					return c->recv_bytes;
				case EINTR:
					break;
				default:
					goto PEER_OVER;
			}
		}
		else if(n_b == 0)
			{	goto PEER_OVER;}
		else{
			
			c->recv_bytes += n_b;
		}
		if(c->recv_bytes == c->total_bytes){
			
			c->data = put_buf;

			mem_map(c);
			c->if_head = 0; 
			c->recv_bytes = 0;
		}
			
	}
#if 0
	ev.data.fd = aEv->data.fd;   
	ev.events = EPOLLIN ;//| EPOLLOUT;   
	ev.events = EPOLLOUT | EPOLLET;   
	epoll_ctl(epfd,EPOLL_CTL_MOD, aEv->data.fd ,&ev);   
#endif

PEER_OVER:
	
	
	shutdown(c->sock_fd,SHUT_WR|SHUT_RD);
	close(c->sock_fd);  
	mem_kick(c);
	epoll_ctl(ep, EPOLL_CTL_DEL, c->sock_fd, &un_use);
	
	CON_PEER(c,"",-1,NULL,-1);

	return EXC_OK;
}


static int sock_init()
{
	
	struct sockaddr_in my_addr;

	listener = -1;
	
	if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
		return EXC_ERROR;
		
	bzero(&my_addr, sizeof(my_addr)); 
	my_addr.sin_family = PF_INET; 
	my_addr.sin_port = htons(SOCK_PORT); 
	my_addr.sin_addr.s_addr = INADDR_ANY; 
	
	if(sock_set(listener) == EXC_ERROR)
		return EXC_ERROR;
		
	if (bind (listener, (struct sockaddr *)&my_addr,
			sizeof(struct sockaddr))== -1)
		return EXC_ERROR;  

	if (listen(listener, LISTEN_NUM) == -1)
		return EXC_ERROR;
	
	if(mon_nonblocking(listener) ==-1)
		return EXC_ERROR;
	
	return listener;
	
}


static int check_con(const char* sock_addr)
{
		int i ;
		if(sock_addr == NULL) return EXC_ERROR;
		
		for(i = 1; i < LISTEN_NUM; i++){
			if(strcmp(sock_cons[i].sock_addr,sock_addr) == 0){
				//close(sock_cons[i].sock_fd);
				return -1;
			}
			if(strlen(sock_cons[i].sock_addr) < 1)
				return i;
			else continue;
		}
 	return EXC_ERROR;
}


static int sock_epoll_init()
{
	
	struct epoll_event ee;
	sock_con_s *con_accpet;
	int epoll_lis ;
	
	if((epoll_lis = sock_init()) == EXC_ERROR)
		return EXC_ERROR;
		
	memset(sock_cons,0x00,sizeof(sock_cons));
	
	
	if(mem_init(0) != 0) return EXC_ERROR;
	
	con_accpet = &sock_cons[0];
	CON_ACC(con_accpet, epoll_lis, accpet_init);
	
	if((ep = epoll_create(LISTEN_NUM)) == -1)
		return EXC_ERROR;
		
	ee.events = EPOLLIN|EPOLLET;
	ee.data.ptr = (void *)(uintptr_t)con_accpet;
	
	if (epoll_ctl(ep, EPOLL_CTL_ADD, epoll_lis, &ee) == -1)
		return EXC_ERROR;
	 
	event_list = mem_alloc(
		sizeof(struct epoll_event) * LISTEN_NUM);
	
	if(event_list == NULL)
		return EXC_ERROR;
		
	return epoll_lis;
	
}


static int epoll_process()
{
	
	sock_con_s *con_sock;
	uint32_t revents;
	int events;	
	int i,c;
	int listen_fd ;
	if((listen_fd = sock_epoll_init()) <= 0){
		close(ep);
		close(listen_fd);
		return EXC_ERROR;
	}
	/*indefinitely*/
	while(1){
		
		events = epoll_wait(ep, event_list, LISTEN_NUM, -1);
		if(errno == EINTR) continue;
		if(events == -1) 
			break;
			
		/* Time out ?Impossible */
		if(events == 0 ) 
			break;
		
		for(i = 0; i < events; i++){
			
			con_sock = event_list[i].data.ptr;
			revents = event_list[i].events;
	
			if( con_sock->sock_fd == listen_fd ){   
				
				con_sock->sacpt(con_sock);
				
				continue;   
			 }
			if ((revents & (EPOLLERR|EPOLLHUP))
				&& (revents & (EPOLLIN)) == 0){
				revents |= EPOLLIN;
			}
			
			if( revents & EPOLLIN ){
			    if(event_list[i].data.fd < 0)   
			        continue;   
			   con_sock->srecv(con_sock);
			}
#if 0		
			if( revents & EPOLLOUT ){
				if(event_list[i].data.fd  < 0 )   
		        continue;   
			}

		
			if (revents & (EPOLLERR|EPOLLHUP))
				continue;
#endif
		}
	
	}
	close(ep);
	close(listen_fd);
	return EXC_ERROR;
	
}


static int accpet_init(sock_con_s *c)
{

	struct sockaddr_in peer_addr;
	socklen_t sock_len;
	
	struct sockaddr	rem_addr;
	struct epoll_event ee;
	
	int accp_fd;
	int i;
	sock_con_s *peer_sock;
	
	

	while(1){
		
		sock_len = sizeof(peer_addr);
		bzero(&peer_addr, sock_len);
		accp_fd = accept(listener,(struct sockaddr *)&peer_addr,
			&sock_len);
		if (accp_fd < 0)
		{
			
			switch(errno){
				//case 	EINTR:
				case ECONNABORTED:
					continue;
				case EAGAIN:
					return EXC_OK;
				default:
					return EXC_ERROR;
			}
		}
  	
  	if(mon_nonblocking(accp_fd) == -1){
  		 close(accp_fd);
  		 continue;
		
		}
		
		

		i = check_con(inet_ntoa(peer_addr.sin_addr));
		if(i < 0) {

			shutdown(accp_fd,SHUT_WR|SHUT_RD);
			close(accp_fd);
			continue;
		}
		else{
			ee.events = EPOLLIN|EPOLLET;
			ee.data.ptr =(void *)(uintptr_t)(&sock_cons[i]);
			if (epoll_ctl(ep, EPOLL_CTL_ADD, accp_fd, &ee) < 0) {
				shutdown(accp_fd,SHUT_WR|SHUT_RD);
				close(accp_fd);
				continue;
			}
			else{
				peer_sock = (sock_con_s*)&sock_cons[i];
  			CON_PEER(peer_sock, inet_ntoa(peer_addr.sin_addr), 
  			accp_fd, epoll_recv, i);
  			continue;
  	}
  	continue;
		}
	}
	
}

 

 

 

分享到:
评论

相关推荐

    nginx优化详细

    通过一个百万并发的nginx反向代理服务器的配置文件优化选项

    Nginx+Tomcat负载均衡

    &lt;Engine name="Catalina" defaultHost="localhost" jvmRoute=" tomcatX"&gt; tomcatX 在这里表示不同的tomcat,我的两个 tomcat 分别使用 tomcat1和tomcat2;来区分。 这个设置是主要用以tomcat的集群。 如果看不懂可以...

    nginx-1.18.0.zip

    Nginx是一个高性能的HTTP和反向代理服务器,...在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于Epoll的高效事件模型kqueue.

    Nginx 1.22.0 Linux 版本,解压安装。

    Nginx 1.22.0 Linux 版本,解压安装。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理...能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。

    Nginx配置文件详细说明

    #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 worker_connections 1024;#单个后台worker process进程的最大并发链接数 # multi_accept on; } ……...

    Nginx 1.22.0 Windows版本,解压安装。

    Nginx 1.22.0 Windows版本,解压安装。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)...能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。

    nginx源码浅析 1.4.0版本

    比较详细的分析了nginx关键源码,包括配置文件解析,进程模式,nginx epoll机制,http反向代理机制,http头读取

    Nginx:取代apache的高性能服务器

    Nginx选择了epoll和kqueue作为网络I/O模型,在高连接并发的情况下,Nginx是Apache服务器不错的替代品,它能够支持高达50 000个并发连接数的响应,运行稳定,且内存、CPU等系统资源消耗非常低。, 本书主要分为4个部分...

    实战Nginx_取代Apache的高性能Web服务器].张宴.扫描版

    Nginx选择了epoll和kqueue作为网络I/O模型,在高连接并发的情况下,内存、 CPU等系统资源消耗非常低,运行稳定。  本书系统地介绍了Nginx与PHP、RUBY、Python结合的使用方法,Nginx作为反向代理与负载均衡的配置与...

    实战Nginx:取代Apache的高性能Web服务器 中文版

    nginx选择了epoll和kqueue作为网络i/o模型,在高连接并发的情况下,内存、cpu等系统资源消耗非常低,运行稳定。  本书系统地介绍了nginx与php、ruby、python结合的使用方法,nginx作为反向代理与负载均衡的配置与...

    nginx-1.0.4 服务器软件下载

    能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。  Nginx作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP...

    30道Nginx面试题含答案(很全)

    在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。 Nginx支持热部署,几乎可以做到7*24小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件...

    Nginx反向代理服务器

    能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。 Nginx作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理...

    NginX VS2013工程

    自己搞的一个VS2013的nginx工程。 没用GnuMake和Msys之类。...epoll和poll肯定是用select了。 不过对于初学者,需要单步调试nginx来熟悉流程的话还是有点用处的 免责:本工程继承并尊重nginX的相关开源协议。

    nginx v1.5.9 for windows

    笔者邮箱: xiong rh@sina com"&gt;Nginx for Windows v1 5 9 Nginx是一款轻量级的Web服务器 反向代理服务器及电子邮件IMAP POP3)代理服务器 并在一个BSD like 协议下发行 Nginx由俄罗斯的程序设计师Igor Sysoev所...

    nginx-1.0.5.zip服务器

    能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。 Nginx作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理...

    nginx v1.5.9 for windows 源程序

    笔者邮箱: xiong rh@sina com"&gt;Nginx for Windows v1 5 9 source code Nginx是一款轻量级的Web服务器 反向代理服务器及电子邮件IMAP POP3)代理服务器 并在一个BSD like 协议下发行 Nginx由俄罗斯的程序设计师...

    深入理解Nginx 模块开发与架构解析

    1.13.6,代码量也日渐庞大,但是由于其核心思想并没改变,为了降低阅读难度,我选择的是nginx-1.0.15版本,并且由于时间和水平有限,重点关注的是nginx的启动以及进程模型、事件模块中的epoll模块、负载均衡以及整体的框架...

    nginx-1.14.0.tar.gz和nginx-1.14.0.zip(Linux和windows)

    能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型. 作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。...

    nginx 配置 安装包 使用命令

    能够支持高达 50,000 个并发连接数的响应,感谢Nginx为大家选择了 epoll and kqueue作为开发模型。 服务器 Nginx作为负载均衡服务:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP...

Global site tag (gtag.js) - Google Analytics