epoll服务器

epoll  :  进行创建epoll_event 变量ev,ev用于注册事件,数组用于回传要处理的事件*****(PS:这个很重要,数组不参与事件的注册中,它只回传需要处理的事件,相当于中介,起数据中继的作用,只需要在epoll_wait中当做参数2即可。int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout); 初始化变量后生成epoll专用的文件描述符--epoll_create(),注册事件 epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev),然后就是主题for(;;)代码,进行wait阻塞等待,并处理返回的发生的事件,下面是我自己实现的并发epoll服务器实例,测试可以多个C进行连接发送。

server.h

#pragma once
#include<iostream>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<bits/stdc++.h>
using namespace std;
#include<sys/epoll.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#define MAX_CLIENTS 10

using namespace std;

namespace ser{
	class server{
		public:
		static int Socket(){
			 int sd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
			if(sd<0)
					exit(1);
			else
					return sd;
		}

		static bool Bind(int sd,uint32_t port){
			struct sockaddr_in laddr;
			laddr.sin_family=AF_INET;
			laddr.sin_port=htons(port);
			//laddr.sin_addr.s_addr=INADDR_ANY;
			inet_pton(AF_INET,"0.0.0.0",&laddr.sin_addr);
			if(bind(sd,(const sockaddr*)&laddr,(socklen_t)sizeof laddr)<0)
					exit(1);
			return true;
		}

		static bool Listen(int sd){
			if(listen(sd,6)<0)
					exit(1);
			return true;
		}
	};
}

e_s.h

#include"s.h"

namespace e_s{
	class epoll_s{
			private:
		int l_sd;
		int port;
			public:
		epoll_s(int _port):port(_port){}
		void Init(){
			l_sd=ser::server::Socket();
			if(ser::server::Bind(l_sd,port)<0){
				exit(1);
			}
			if(ser::server::Listen(l_sd)<0){
				exit(1);
			}
		}
		
			//use epoll  主要代码 
		 void Run(){
				 cout<<"Runing..."<<endl;
				struct epoll_event ev,evs[MAX_CLIENTS];//进行epoll_event的变量的初始化和其数组的初始化,数组只是用来隐含地返回发生的时间的描述符 只有在epoll_wait时才会用到数组 epoll_wait(int epfd,struct epoll_event* evs,int max_evs,int time_out)
				ev.data.fd=l_sd;//进行epoll_event变量的赋值 监听的对象,监听对象的监听的事件 l_sd  EPOLLIN 可读事件
				ev.events=EPOLLIN;
				struct epoll_event mid_ev;//临时变量epoll_evennt其实也可以不需要 因为用ev就行了 目的就是添加到epoll描述符(epoll_create 返回值)中

				int e_fd=epoll_create(2);//epoll描述符

				epoll_ctl(e_fd,EPOLL_CTL_ADD,l_sd,&ev); //增加监听的对象

				while(true){
					cout<<"Ready for waiting!"<<endl;
					int num=epoll_wait(e_fd,evs,MAX_CLIENTS,-1);//阻塞等待
					cout<<"wait is over."<<endl;
					//cout<<"num is "<<num<<endl;
					for(int i=0;i<num;++i){
						if(evs[i].data.fd==l_sd){//是监听的对象改变了  说明有新的连接
								struct sockaddr_in raddr;
								socklen_t len;
								int new_sd=accept(l_sd,(struct sockaddr*)&raddr,&len);
								char str[1024];
								inet_ntop(AF_INET,&raddr.sin_addr,str,sizeof str);
								cout<<"connected by"<<str<<" port:"<<ntohs(raddr.sin_port)<<endl;
								mid_ev.data.fd=new_sd;//将连接的描述符进行监视对象的初始化
								mid_ev.events=EPOLLIN;
								epoll_ctl(e_fd,EPOLL_CTL_ADD,new_sd,&mid_ev);//将连接的描述符进行添加到监视队列中
						}
						else
						{
							//连接对象发生改变 说明对端发来了消息
							char buf[1024];
							int n=read(evs[i].data.fd,buf,sizeof buf);
							buf[n]='\0';
							cout<<"Receive : "<<buf<<endl;
						}
					}
				}
		 }
	};
}

e_s.cpp

#include"e_s.h"

int main(int argc,char** argv){
		e_s::epoll_s* s=new e_s::epoll_s(atoi(argv[1]));
		s->Init();
		s->Run();
	return	 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值