epoll c和c++的简单例子(纯代码)

这一次贴出epoll的一个简单例子,关于epoll的一些介绍网上很多,我也写了一个简单的介绍:epoll简单介绍
下面分别贴出c和c++的同一份实现代码:用于测试多个客户端和一个服务端的连接

客服端代码:

//tcp server 并发服务器 客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <ctype.h>
#include <arpa/inet.h>
#define 	SERV_PORT 9999        

int tcp_client_init(){
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd == -1){
		printf("socket failed!\n");
		return -1;
	}
	
	struct sockaddr_in serv_addr;
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERV_PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //任意的IP地址
	
	int ret = connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
	if(ret == -1){
		printf("connect error!\n");
		return -2;
	}
	
	//connect success
	write(sockfd,"connect success\n",20);
	
	while(sockfd != -1){
		
	}  //等待
	
	close(sockfd);
	return sockfd;
}

int main(){
	tcp_client_init();
}

服务端:
C语言:

//tcp server epoll并发服务器 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <sys/epoll.h>
#define  MAX_LINK_NUM   128
#define  SERV_PORT      8888
#define  BUFF_LENGTH    320
#define  MAX_EVENTS     5

int  count = 0;

int tcp_epoll_server_init(){
	
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd == -1){
		printf("socket error!\n");
		return -1;
	}
	
	struct sockaddr_in serv_addr;
	struct sockaddr_in clit_addr;
	socklen_t clit_len;
	
	
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERV_PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);// 任意本地ip
	
	int ret = bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
	if(ret == -1){
		printf("bind error!\n");
		return -2;
	}
	
	listen(sockfd,MAX_LINK_NUM);
	
	
	//创建epoll
	int  epoll_fd = epoll_create(MAX_EVENTS);
	if(epoll_fd == -1){
		printf("epoll_create error!\n");
		return -3;
	}
	
	//向epoll注册sockfd监听事件
	struct epoll_event ev;   //epoll事件结构体
	struct epoll_event events[MAX_EVENTS];  //事件监听队列
	
	ev.events = EPOLLIN;
	ev.data.fd = sockfd;
	
	int ret2 = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,sockfd,&ev);
	if(ret2 == -1){
		printf("epoll_ctl error!\n");
		return -4;
	}
	int connfd = 0;
	while(1){
	
		//epoll等待事件
			int nfds = epoll_wait(epoll_fd,events,MAX_EVENTS,-1);
			if(nfds == -1){
				printf("epoll_wait error!\n");
				return -5;
			}
			printf("nfds: %d\n",nfds);
			//检测
			for(int i = 0;i<nfds;++i){
				//客服端有新的请求
				if(events[i].data.fd == sockfd){
					 connfd =  accept(sockfd,(struct sockaddr*)&clit_addr,&clit_len);
					if(connfd == -1){
						printf("accept error!\n");
						return -6;
					}
					
					ev.events = EPOLLIN;
					ev.data.fd = connfd;
					if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,connfd,&ev) == -1){
						printf("epoll_ctl add error!\n");
						return -7;
					}
					
					printf("accept client: %s\n",inet_ntoa(clit_addr.sin_addr));
					printf("client %d\n",++count);
				}
				//客户端有数据发送过来
				else{
					char buff[BUFF_LENGTH];
					int ret1 = read(connfd,buff,sizeof(buff));
					printf("%s",buff);
				}
			}
		
	}
	
	close(connfd);
	return 0;
	
}

int main(){
	tcp_epoll_server_init();
}

c++:只是进行了一层简单封装,其实没什么区别

#include <iostream>
#include <vector>   //向量存储
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
using namespace std;


#define    MAX_NUM   1024


class MyEpoll{
    public:
    MyEpoll();
    ~MyEpoll();

    int epoll_create();
    int epoll_add(int listenfd);
    int epoll_del(int listenfd);
    int epoll_mod(int listenfd);
    int myepoll_wait();
    struct epoll_event* getEvent();

    private:
    int epfd;
    int epoll_events_max_nums;
    struct epoll_event * events;   //就绪队列
};

MyEpoll::MyEpoll(){
    this->epfd = -1;
    this->epoll_events_max_nums = MAX_NUM;
    this->events = NULL;
}



MyEpoll::~MyEpoll(){
    if(epfd > 0){
        close(epfd);
    }

    if(events != NULL){
        delete[] this->events;
        this->events = NULL;
    }
}

int MyEpoll::epoll_create(){
    this->epfd = epoll_create(1);
    if(epfd == -1){
        printf("epoll_create error\n");
        return -1;
    }
    if(events != NULL){
        delete [] events;
    }

    events = new epoll_event[epoll_events_max_nums];
}


int MyEpoll::epoll_add(int listenfd){
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;

    epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
}

int MyEpoll::epoll_del(int listenfd){
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;

    epoll_ctl(epfd,EPOLL_CTL_DEL,listenfd,&ev);
}

int MyEpoll::epoll_mod(int listenfd){
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;

    epoll_ctl(epfd,EPOLL_CTL_MOD,listenfd,&ev);
}

int MyEpoll::myepoll_wait(){
    int nfds = epoll_wait(epfd,events,MAX_NUM,-1);
    return nfds;
}

struct epoll_event* MyEpoll::getEvent(){
    return events;
}

#define  SERV_PORT       9999
#define  BUFF_LENGTH     320

int main(){
    MyEpoll myepoll;
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd == -1){
		printf("socket error!\n");
		return -1;
	}
	
	struct sockaddr_in serv_addr;
	struct sockaddr_in clit_addr;
	socklen_t clit_len;
	
	
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERV_PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);// 任意本地ip
	
	int ret = bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
	if(ret == -1){
		printf("bind error!\n");
		return -2;
	}
	
	listen(sockfd,MAX_LINK_NUM);

    myepoll.epoll_create();
    myepoll.epoll_add(sockfd);
    int connfd = 0;
    int count = 0;
    for(;;){
        int nfds = myepoll.myepoll_wait();
        if(nfds == -1){
				printf("epoll_wait error!\n");
				return -5;
			}
			printf("nfds: %d\n",nfds);
    struct epoll_event *events = myepoll.getEvent();
    for(int i = 0;i<nfds;++i){
				//客服端有新的请求
				
				if(events[i].data.fd == sockfd){
					 connfd =  accept(sockfd,(struct sockaddr*)&clit_addr,&clit_len);
					if(connfd == -1){
						printf("accept error!\n");
						return -6;
					}
                    myepoll.epoll_add(connfd);
					
					printf("accept client: %s\n",inet_ntoa(clit_addr.sin_addr));
					printf("client %d\n",++count);

    }
    else{
					char buff[BUFF_LENGTH];
					int ret1 = read(connfd,buff,sizeof(buff));
					printf("%s",buff);
				}
    
}
    }
}

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

Achi_Lyr

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值