边缘触发模式+非阻塞读取网络IO

测试扩容:原来业务处理读取数据是if,改成while,如果有数据发送读取完毕就会阻塞,一个线程绑定一个客户端,这样就会导致线程一直被占用。

测试完扩容以后,用不用改回来?不改回来导致线程被占用。if读一次也不是一件好事 ,recv读我们规定的大小 ,如果读不完怎么办,网络情况变换莫测,可能我们想读500字节,实际上只读取了300字节,且边缘触发模式,clientfd就绪,就发送一次通知,读不读,读没读完,无法确定。

肯定不能读一次 ,采用边缘触发模式+非阻塞读取网络IO。
边缘触发是因为只希望当某个socket就绪,只希望发一次通知。非阻塞是因为阻塞的读取socket,读取完所有数据以后,recv函数阻塞导致线程被占用,非阻塞循环读取,读完后立即返回,不会阻塞。
如何非阻塞读取?
方法一:将网络IO sockfd通过文件属性fctl函数 ,变为非阻塞sockfd。
方法二:不改变sockfd的属性,改变recv函数的读取方式,将recv函数改成非阻塞读取。

#include<THREAD_POOL.h>
void *BUSINES_RESPONSE(void *arg)
{
	int clientfd;
	clientfd = *(int*)arg;
	char buffer[BUFSIZE];
	bzero(buffer,BUFSIZE);
	int recvsize ,sendsize;
	int flags;
   //原来是if((recvsize = RECV(clientfd,buffer,sizeof(buffer),0))>0)
	while((recvsize = RECV(clientfd,buffer,sizeof(buffer),0))>0){
		flags = 0;
		while(recvsize > flags){
			buffer[flags] = toupper(buffer[flags]);
			flags++;
		}
		sendsize = SEND(clientfd,buffer,recvsize,0);
		printf("CUSTOMER EXEC BUSINES_RESPONSE RECV REQUET [%d] SEND RESPONSE [%d]\n",recvsize,sendsize);
	}
       if(recvsize == 0){
		printf("CUSTOMER EXEC BUSINES_RESPONSE CLIENT EXIST ...\n");
		epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,NULL);
		close(clientfd);

	}
	return NULL;
}
//连接业务
#include<THREAD_POOL.h>

void *BUSINES_ACCEPT(void *arg) //传过去的是sockfd
{
	struct epoll_event node; //用于将clientfd添加到监听树上创建的节点

	int serverfd;
	serverfd = *(int*)arg;

	int clientfd;
	struct sockaddr_in clientaddr;
	socklen_t addrlen;
	addrlen = sizeof(clientaddr);

	char ip[IPSIZE];
	bzero(ip,IPSIZE);
	int flags;

	if((clientfd = ACCEPT(serverfd,(struct sockaddr *)&clientaddr ,&addrlen))>0){ //连接成功需要将clientfd添加到监听树上
	    //采用方法一将clientfd改成非阻塞
		flags = fcntl(clientfd,F_GETFL,NULL);  
		fcntl(clientfd,F_SETFL,flags|O_NONBLOCK); 

		printf("CUSTOMER EXEC BUSINES_ACCEPT CONNECTTION SUCCESS CLIENT[%s][%d] clientfd[%d]\n",
			inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,ip,IPSIZE),ntohs(clientaddr.sin_port),clientfd);

		node.data.fd = clientfd;
		node.events = EPOLLIN|EPOLLET; //监听读事件 
		if((epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,&node))==-1) //epfd定义为全局  //连接成功需要将clientfd添加到监听树上
			thread_pool_error("BUSINES_ACCEPT epoll_call failed",-1,FALSE);
	}

	return NULL;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值