`
sunzixun
  • 浏览: 76540 次
  • 性别: 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_https+tomcat_http配置.docx

    &lt;stopexecutable&gt;D:\work\nginx_13_Violet\nginx.exe&lt;/stopexecutable&gt; &lt;stoparguments&gt;-p D:\work\nginx_13_Violet -s stop&lt;/stoparguments&gt; &lt;/service&gt; ``` **nginx-service.exe.config** ```xml ...

    nginx优化详细

    ### Nginx优化详细知识点 #### 一、Nginx 运行工作进程个数的优化 - **重要性**:Nginx 的工作进程数直接影响到其处理并发请求的能力和资源利用效率。 - **配置建议**:推荐将 `worker_processes` 设置为 CPU 核心...

    nginx 安装配置详解

    - 解压并进入目录:`tar zxf nginx-&lt;version&gt;.tar.gz && cd nginx-&lt;version&gt;` - 配置编译选项:`./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module` - 编译及安装:...

    nginx tomcat集群 session复制

    - 在每个Tomcat实例的`conf/server.xml`中启用`&lt;Manager&gt;`元素的`sessionBackup`属性,配置为`true`,并设置相同的`sessionIDManager`。 - 使用`&lt;Cluster&gt;`元素定义集群,包括`node`和`sessionIDGenerator`等属性...

    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 配置说明文档

    Nginx 的事件处理机制是基于 epoll 机制的,例如,`use epoll;` 指定 Nginx 使用 epoll 机制来处理事件。这个设置对 Nginx 的性能和稳定性有很大的影响。 HTTP 服务器配置 Nginx 的 HTTP 服务器配置是指 Nginx 的 ...

    Nginx 1.22.0 Linux 版本,解压安装。

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

    Nginx 1.22.0 Windows版本,解压安装。

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

    详解nginx rewrite和根据url参数location

    其中,`&lt;regex&gt;` 是正则表达式,`&lt;replacement&gt;` 是替换后的 URL,`[flag]` 可选标志,如 `last`(停止当前规则集的匹配)、`break`(跳出当前规则)、`redirect`(返回重定向)等。 3. **示例** 例如,将所有以 ...

    开源电子书:Nginx 开发手册文档.pdf

    8. kqueue、epoll、rt signals、/dev/poll 和 select 支持:Nginx 支持多种事件机制,包括 kqueue、epoll、rt signals、/dev/poll 和 select,可以根据需要选择合适的事件机制。 9. sendfile 支持:Nginx 支持 send...

    Nginx 配置文件 nginx.conf 详解

    事件处理模型是 Nginx 服务器处理客户端请求的重要组件,我们可以通过 `use` 指令来设置事件处理模型,例如 `use epoll;`,这将设置事件处理模型为 epoll。 客户端请求头部缓冲区大小 客户端请求头部缓冲区大小是 ...

    Nginx高性能Web服务器详解(完整版)pdf下载

    2. **事件驱动模型**:Nginx使用Epoll(Linux)或KQueue(FreeBSD)等高效I/O复用技术,实现非阻塞I/O,使得在处理大量并发连接时性能优秀。 3. **反向代理**:Nginx可以作为反向代理服务器,将客户端请求转发到...

    Nginx 核心模块与配置实践 (1)1

    `显示帮助,`./nginx`启动服务器,`./nginx -c /path/to/nginx.conf`指定配置文件启动,`nginx -s reload`或`kill -HUP &lt;nginx进程PID&gt;`用于平滑重载配置。 在配置实践中,Nginx的灵活性体现在其模块化设计。它可以...

    Nginx配置文件详细说明

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

    Nginx安装+nginx_upstream_check_module后端健康检查

    patch -p0 &lt; ../nginx_upstream_check_module-master/check_1.9.2+.patch ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module --with-http_stub_status_module --with-pcre \ --with-...

    nginx-1.2.4(最新稳定版)

    6. **高性能并发**:Nginx采用epoll事件模型,可以处理成千上万的并发连接,尤其适合高流量的网站。 7. **错误页面定制**:Nginx允许自定义404、500等错误页面,提升用户体验。 在实际部署中,Nginx通常与动态语言...

    nginx.config_nginx_

    - `events`块用于配置Nginx如何处理连接事件,如`events { use epoll; worker_connections 1024; }`,其中`use`指定事件模型(如epoll),`worker_connections`指每个工作进程的最大连接数。 3. **http块** - `...

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

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

    nginx-1.19.2.tar.gz

    其基于epoll(Linux)或kqueue(FreeBSD)等高效I/O复用机制,优化了处理速度。 2. **反向代理和负载均衡**:Nginx 可以作为反向代理服务器,将来自客户端的请求转发到后端服务器集群,同时支持基于多种策略(如...

Global site tag (gtag.js) - Google Analytics