【网络编程实例】C++实现基于I/O复用epoll函数的服务器和客户端通信
admin
2024-02-17 01:12:54
0

参考《TCP/IP网络编程第17章》

epoll函数

  • epoll函数的优点:
    • 无需编写以监视状态变化为目的的针对所有文件描述符的循环语句;
    • 调用对应于 select 函数的 epoll_wait 函数时无需每次传递监视对象信息。
  • epoll 函数的功能:
    • epoll_create:创建保存 epoll 文件描述符的空间;
    • epoll_ctl:向空间注册并注销文件描述符;
    • epoll_wait:与 select 函数类似,等待文件描述符发生变化;
  • epoll_event 结构体:
    • 用于保存事件的文件描述符结合;
    • epoll_event 的成员 events 中可以保存的常量及所指的事件类型:
      • EPOLLIN:需要读取数据的情况
      • EPOLLOUT:输出缓冲为空,可以立即发送数据的情况
      • EPOLLPRI:收到 OOB 数据的情况
      • EPOLLRDHUP:断开连接或半关闭的情况,这在边缘触发方式下非常有用
      • EPOLLERR:发生错误的情况

实现基于epoll函数的服务器和客户端通信

  • 服务器端代码
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #include 
#include using std::cout;
using std::cin;
using std::string;
using std::endl;#define BUF_SIZE 1024
#define EPOLL_SIZE 50
#define SERVER_IP "127.0.0.1"    // 指定服务端的IP
#define SERVER_PORT 9190            // 指定服务端的portint main()
{int serv_sock, clnt_sock;struct sockaddr_in serv_adr, clnt_adr;socklen_t adr_sz;int str_len, i;char buf[BUF_SIZE];struct epoll_event *ep_events;struct epoll_event event;int epfd, event_cnt;serv_sock = socket(PF_INET, SOCK_STREAM, 0);bzero(&serv_adr, sizeof(serv_adr));serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);serv_adr.sin_port = htons(SERVER_PORT);if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) cout << "Bind error" << errno << ": " << strerror(errno) << endl;if(listen(serv_sock, 5) == -1) cout << "Listen error" <<  errno << ": " << strerror(errno) << endl;epfd = epoll_create(EPOLL_SIZE);//可以忽略这个参数,填入的参数为操作系统参考ep_events = (struct epoll_event*)malloc(sizeof(struct epoll_event) * EPOLL_SIZE);event.events = EPOLLIN;//需要读取数据的情况event.data.fd = serv_sock;//例程epfd 中添加文件描述符 serv_sock,目的是监听 enevt 中的事件epoll_ctl(epfd, EPOLL_CTL_ADD,serv_sock, &event);while(1){event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, - 1);//获取改变了的文件描述符,返回数量if(event_cnt == -1) {cout << "epoll_wait() error" << endl;break;}for(i = 0; i < event_cnt; ++i) {if(ep_events[i].data.fd == serv_sock)//客户端请求连接时{adr_sz = sizeof(clnt_adr);clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz);event.events = EPOLLIN;event.data.fd = clnt_sock;//把客户端套接字添加进去epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event);cout << "connected client:" << clnt_sock << endl;}else //是客户端套接字时{str_len = read(ep_events[i].data.fd,buf, BUF_SIZE);if(str_len == 0){epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[i].data.fd, &event);close(ep_events[i].data.fd);cout << "closed client:" << ep_events[i].data.fd << endl;}else{write(ep_events[i].data.fd,buf, str_len);}}}}close(serv_sock);close(epfd);return 0;
}
  • 客户端代码
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #include 
#include using std::cout;
using std::cin;
using std::string;
using std::endl;#define BUFFSIZE 1024
#define SERVER_IP "127.0.0.1"    // 指定服务端的IP
#define SERVER_PORT 9190            // 指定服务端的portint main()
{int sock;char message[BUFFSIZE];int str_len;struct sockaddr_in serv_adr;sock = socket(PF_INET, SOCK_STREAM, 0);if(sock == -1) cout << "socket() error" << endl;bzero(&serv_adr, sizeof(serv_adr));serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr = inet_addr(SERVER_IP);serv_adr.sin_port = htons(SERVER_PORT);if(connect(sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) == -1)cout << "connect() error: " << errno << " " << strerror(errno) << endl;elsecout << "connected............" << endl;while(1){cout << "Input message(Q to quit): " << endl;cin >> message;if(!strcmp(message, "q") || !strcmp(message, "Q"))break;write(sock, message, strlen(message));str_len = read(sock, message, BUFFSIZE - 1);message[str_len] = 0;cout << "Message from server:" << message << endl;}close(sock);return 0;
}

相关内容

热门资讯

安卓系统打开动画效果,打开动画... 你有没有发现,每次打开安卓手机,那瞬间闪现的动画效果,就像是一场视觉盛宴呢?今天,就让我带你一起探索...
安卓系统的诞生和发展,安卓系统... 你有没有想过,手机里的那个小小的操作系统,竟然能改变我们的生活呢?没错,我要说的就是安卓系统。它就像...
安卓系统电话通话录音,捕捉真实... 你有没有想过,在繁忙的生活中,有时候一个电话的录音就能帮你回忆起重要的信息或者关键时刻的对话内容呢?...
安卓64位系统官方下载,解锁全... 你有没有发现,最近你的安卓手机好像有点卡卡的呢?别急,别急,今天就来给你揭秘一下如何给你的安卓手机升...
安卓8系统可以吗,创新与变革的... 你有没有听说安卓8系统?最近这个话题在数码圈可是火得一塌糊涂呢!不少朋友都在问我:“安卓8系统可以吗...
安卓系统电量显示不正,揭秘原因... 手机电量显示不准确,是不是你也遇到了这样的烦恼?每次看着那忽上忽下的电量百分比,心里是不是直发慌?别...
安卓平板开票系统怎么用,轻松实... 你有没有想过,拥有一台安卓平板,不仅能随时随地办公学习,还能轻松搞定开票业务呢?没错,现在就让我来带...
安卓系统怎样下载尚德,安卓系统... 你有没有想过,想要在安卓系统上下载尚德,其实就像是在茫茫书海中找到一本宝藏呢?别急,让我来带你一步步...
安卓5系统自带相机软件,系统自... 你有没有发现,自从你升级到了安卓5系统,手机里的相机软件好像变得不一样了呢?没错,就是那个我们每天都...
qq支持安卓机的系统 你有没有发现,最近你的安卓手机上QQ更新了不少新功能呢?没错,QQ这次可是大动作,全面支持安卓机的系...
安卓没有平板操作系统,平板操作... 你知道吗?在科技圈里,最近有个话题可是引起了不小的讨论呢——安卓没有平板操作系统。是不是觉得有点不可...
海信电视有带安卓系统 亲爱的读者们,你是否在寻找一款既时尚又实用的电视呢?今天,我要给你介绍一款特别受欢迎的产品——海信电...
优学派安卓系统不能下载,优学派... 最近发现了一个让人头疼的小问题,那就是优学派安卓系统竟然不能下载应用了!这可真是让人摸不着头脑,毕竟...
安卓系统下载大疆软件,开启航拍... 你有没有想过,无人机飞行器已经不再是那些高科技电影里的专属了?现在,连咱们普通人也能轻松驾驭这些空中...
安卓系统的隐藏相册在哪,隐藏相... 你有没有发现,手机里的安卓系统有时候藏着一些小秘密呢?比如,那个神秘的隐藏相册,它就像一个隐藏的宝藏...
安卓手机分几个软件系统,多元生... 你有没有想过,你的安卓手机里竟然藏着那么多的秘密?没错,就是那些软件系统!今天,就让我带你一探究竟,...
安卓系统鼠标没反应,排查与解决... 亲爱的安卓用户们,你是否曾遇到过这样的烦恼:鼠标在电脑上动来动去,却怎么也控制不了安卓系统的界面?别...
摄像头支持安卓系统,开启智能生... 你有没有发现,现在的生活越来越离不开摄像头了?从家庭监控到手机拍照,从行车记录到无人机航拍,摄像头已...
安卓系统怎么查手机定位,安卓系... 你是不是也和我一样,有时候会突然好奇,想知道自己的手机在哪个角落里“闲逛”呢?别急,今天就来教你怎么...
学生登录系统和安卓手机 你有没有发现,现在的生活越来越离不开手机了?尤其是对于我们这些学生来说,手机简直就是我们的“小助手”...