通过 EPOLL 解决客户端同时连接多服务器的问题

项目需求是  程序上 同时配置了多个服务端 设备

每隔一段时间需要 比如1分钟 连一下服务器看下是否连通  

并将结果上报给平台 

原来是用线程池来做的  

具体大概就是 定时器到了之后 

遍历设备列表  找到设备之后  通过 socket连接 发送一个指令 等待服务器返回 用来检查是否在线 

这样的问题是 如果设备不是很多的话 还好  但是如果 有上百个设备 的话 

每一轮遍历需要很长时间  

后来 看了EPOLL尝试一下  

相当于是改成单线程了  但是效果不是很好  

基本上还是相当于单线程     测试结果感觉还是单线程在跑  

后期改成协程试下看看  

bool QMCY_APP::CreateEPOLL()
{

	m_epoll_fd = epoll_create1(0);
	if (m_epoll_fd < 0)
	{
		printf("epoll_create failed\n");
		return false;
	}

	return true;
}




bool QMCY_APP::Add2Epoll(std::shared_ptr  led)
{
	int fd;
	auto ip = led->NVR_GetIP().c_str();
	auto port = led->NVR_GetPort();


	struct sockaddr_in my_addr;
	socklen_t peer_addr_size;

	

	fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);

	if (fd == -1)
	{
		printf("Add2Epoll Create socket failed\n");
		return false;
	}

	memset(&my_addr, 0, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_addr.s_addr = inet_addr(ip);
	my_addr.sin_port = htons(port);

	int ret = connect(fd, (struct sockaddr*)&my_addr, sizeof(my_addr));

	if (ret == 0) {
		puts("connect successfully!");
		return false;
	}

	if (errno != EINPROGRESS) printf("Add2Epoll success [%s:%d] \n",ip,port);


	struct epoll_event ev;
	
	ev.events = EPOLLOUT |EPOLLET |EPOLLIN;
	ev.data.fd = fd;

	if (epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1)
	{
		printf("epoll_ctl failed\n");
		return false;
	}

	m_led_all.insert(std::pair>(fd,led));
	led->NVR_ResetState();
	return true;
}



bool QMCY_APP::HandleEPOLL()
{
	int timeout = 3000;	
	auto index = 0;

	struct epoll_event events[MAX_EVENTS];

	while(index NVR_GetIP().c_str(),led->NVR_GetPort());

						struct epoll_event ev = {0};
						ev.events = EPOLLET |EPOLLIN;
						ev.data.fd = fd;
						epoll_ctl(m_epoll_fd, EPOLL_CTL_MOD, fd, &ev);

						led->NVR_ProbeOnline(fd);
					}
				}
				else if (events[n].data.fd && (events[n].events & EPOLLIN))
				{
					char buf[BUFSIZ] = {0};
					int nread,n = 0;  
					auto fd = events[n].data.fd;
					while ((nread = read(fd, buf + n, BUFSIZ-1)) > 0) {  
					    n += nread;  
						 printf("n=%d nread=%d\n",n,nread);
					}  
					if (nread == -1 && errno != EAGAIN) {  
					    perror("read error");  
						 continue;
					} 
					auto led = m_led_all[fd];

					printf("11111111Read data success [ip:%s	port:%d read=%d]\n",led->NVR_GetIP().c_str(),led->NVR_GetPort(),n);

					if(n>0)
					{
						led->NVR_ProbeAnalyse(buf,n);						
					}


				}
			}
		}
		index++;
		printf("HandleEPOLL  loop index =%d ~~~~~~~~~~~~~~~~~\n",index);
		//sleep(1);
	}

	printf("HandleEPOLL end exit ~~~~~~~~~~~~~~~~~\n");
	return true;
}


bool QMCY_APP::DestroyEPOLL()
{
	if (m_epoll_fd > 0 ) 
	{
		close(m_epoll_fd);
	}

	return true;
}

你可能感兴趣的:(服务器,运维)