最近看了《linux高性能服务器编程》那本书, 上面描述Rector的一张图

对着这图,自己用c++封装了一下, 不知道有什么不足出,请大神们多多指点下。代码如下:
服务器端代码:

#include <iostream>
#include <unistd.h>
#include <cassert>
#include <cstdlib>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <vector>
#include <map>
#include <fcntl.h>using namespace std;
#define MAX 100
int listenfd;
class Rector;
class Demultiplexer;
class Handle
{
public:Handle(int fd = -1): m_fd(fd) {}virtual ~Handle() {close(m_fd);}virtual void call_back(int fd){}int getfd() const{return m_fd;}
protected:int m_fd;
};class TcpHandle : public Handle
{
public:TcpHandle(int fd) : Handle(fd) {}void call_back(int fd){char buff[1024] = {0};memset(buff, 0, 1024);int n = recv(fd, buff, 1024, 0);if(n < 0)perror("recv error");else if(n == 0)cout << "one client over " << endl;elsecout << "recv data: " << buff << endl;send(fd, "OK", 2, 0);}
};class Demultiplexer
{
public:Demultiplexer(int fd = -1) : epfd(fd){}~Demultiplexer(){close(epfd);}void Register(Handle* handle);void Remove(Handle* handle);void dispatch();void start_listen(int fd, char *ip, int port);private:map<int, Handle*> m_dump;int epfd;struct epoll_event fds[MAX];
};void Demultiplexer::start_listen(int fd, char *ip, int port)
{epfd = epoll_create(MAX);struct sockaddr_in saddr;memset(&saddr, 0, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(port);saddr.sin_addr.s_addr = inet_addr(ip);assert(bind(fd, (struct sockaddr*)&saddr, sizeof(saddr)) != -1);assert(listen(fd, 5) != -1);
}void Demultiplexer::Register(Handle* handle)
{int fd = handle->getfd();struct epoll_event ev;ev.events = EPOLLIN | EPOLLET;ev.data.fd = fd;if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1){perror("epoll_ctl error");return ;}int oldflag = fcntl(fd, F_GETFL);int newflag = oldflag | O_NONBLOCK;if(fcntl(fd, F_SETFL, newflag) == -1){perror("fcntl error");return ;}m_dump.insert(make_pair(fd, handle));
}void Demultiplexer::Remove(Handle* handle)
{int fd = handle->getfd();if(epoll_ctl(epfd, EPOLL_CTL_DEL,fd, NULL) == -1){perror("epoll_ctr error");}m_dump.erase(fd);
}void Demultiplexer::dispatch()
{while(1){int n = epoll_wait(epfd, fds, MAX, -1);switch(n){case -1:perror("epoll_wait error");break;case 0:continue;break;default:{for(int i = 0; i < n; ++i){if(fds[i].data.fd == listenfd){struct sockaddr_in caddr;socklen_t len = sizeof(caddr);int c = accept(fds[i].data.fd, (struct sockaddr*)&caddr, &len);cout << "one client connect ip: " << inet_ntoa(caddr.sin_addr) << " port: "<< ntohs(caddr.sin_port) << endl;Handle *p = new TcpHandle(c);Register(p);}else if(fds[i].events & EPOLLIN){int fd = fds[i].data.fd;map<int, Handle*>::iterator it = m_dump.find(fds[i].data.fd);if(it != m_dump.end()){(it->second)->call_back(fd);}else{m_dump.erase(fd);Remove(new TcpHandle(fd));}}}}break;}}
}class Rector
{
public:static Rector* getInstance(){if(m_rector == NULL){m_rector = new Rector();}return m_rector;}void start(int fd, char *ip, int port){m_demp.start_listen(fd, ip, port);}void Register(Handle *handle){m_demp.Register(handle);}void Remove(Handle* handle){m_demp.Remove(handle);}void handle_event(){m_demp.dispatch();}
private:Rector(){}static Rector* m_rector;Demultiplexer m_demp;
};Rector* Rector::m_rector = NULL;
static Rector* rector = Rector::getInstance();int main(int argc, char* argv[])
{if(argc < 3){cout << "invalid argument" << endl;exit(0);}int port = atoi(argv[2]);listenfd = socket(AF_INET, SOCK_STREAM, 0);assert(listenfd != -1);rector->start(listenfd, argv[1], port);Handle *p = new TcpHandle(listenfd);rector->Register(p);rector->handle_event();  //循环return 0;
}

客户端代码:

#include <iostream>
using namespace std;
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <cassert>
#include <sys/epoll.h>
#include <fcntl.h>
#include <stdio.h>
#include <cstdlib>
#include <errno.h>class Client
{
public:Client(char *ip, int port){sockfd = socket(AF_INET, SOCK_STREAM, 0);assert(sockfd != -1);struct sockaddr_in saddr;bzero(&saddr, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(port);saddr.sin_addr.s_addr = inet_addr(ip);socklen_t len = sizeof(saddr);setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &saddr, len);if(connect(sockfd, (struct sockaddr*)&saddr, len) < 0){cout << errno << endl;perror("connect error");}}void sendData(char *buff) {send(sockfd, buff, strlen(buff), 0);}void recvData(char *buff) {recv(sockfd, buff, 1024, 0);}int getfd() const{return sockfd;}
private:int sockfd;
};int main(int argc, char *argv[])
{if(argc < 3){cout << "Invalid argument !" << endl;exit(0);}int port = atoi(argv[2]);Client cli(argv[1], port);char buff[1024] = {0};while(1){memset(buff, 0, 1024);cin.getline(buff, 1024);cli.sendData(buff);memset(buff, 0, 1024);cli.recvData(buff);cout << "recv data: " << buff << endl;}return 0;
}

c++封装Rector相关推荐

  1. IDEA中将代码块封装为方法,IDEA代码重构快捷键

    IDEA中将代码块封装为方法 选中要转换的代码块,快捷键: Windows快捷键:Alt + Shift + M Mac快捷键:Alt + Command + M 如图:

  2. 2022-2028年中国封装用胶膜行业运营现状及投资发展潜力报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了封装用胶膜行业相关概述.中国封装用胶膜行业运行环境.分析了中国封装用 ...

  3. 第十六节,使用函数封装库tf.contrib.layers

    目录 一 tf.contrib.layers中的具体函数介绍 1.tf.contrib.layers.conv2d()函数的定义如下: 2.tf.contrib.layers.max_pool2d() ...

  4. 薄膜封装,等离子体技术,原子层沉积,化学气相沉积

    薄膜封装,等离子体技术,原子层沉积,化学气相沉积 薄膜封装 薄膜封装概念 薄膜真空沉积的一个很重要的技术应用就是薄膜封装.人们对薄膜封装最简单的认识就是日常生活中最常见的保鲜膜,水氧渗透率大约是1-1 ...

  5. 为什么要使用Retrofit封装OkHttp,而不单独使用OkHttp?

    OkHttp的优点: 开源的轻量级框架.高效.快速的请求客户端,可以单独使用它来实现网络请求. 支持SPDY: 支持连接池,可极大减少延时: 支持Gzip压缩响应体,降低传输内容的大小: 支持Http ...

  6. Python Day26:多态、封装、内置函数:__str__、__del__、反射(反省)、动态导入模块...

    ## 多态 ```python OOP中标准解释:多个不同类型对象,可以响应同一个方法,并产生不同结果,即为多态 多态好处:只要知道基类使用方法即可,不需要关心具体哪一个类的对象实现的,以不变应万变, ...

  7. 09_Java面向对象_第9天(类、封装)_讲义

    今日内容介绍 1.面向对象思想 2.类与对象的关系 3.局部变量和成员变量的关系 4.封装思想 5.private,this关键字 6.随机点名器 01面向对象和面向过程的思想 A: 面向过程与面向对 ...

  8. Appium的Java封装

    文章出处 http://blog.csdn.net/niubitianping/article/details/52612211 一.为什么需要封装? 封装的本意就是为了方便.简洁. 二.Androi ...

  9. Go 学习笔记(36)— 基于Go方法的面向对象(封装、继承、多态)

    Go 面向对象编程的三大特性:封装.继承和多态. 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不 ...

最新文章

  1. 利用闭包实现多次ajax请求只执行最后一次
  2. C~K要找女朋友了!!!_JAVA
  3. LeetCode Algorithm 242. 有效的字母异位词
  4. 2020年产业互联网发展报告
  5. 618购物节要到了,Python帮你实现商品有货的微信提醒
  6. react入门(1)之阮一峰react教程
  7. python编程100个小程序-(编程)10个Python练手小程序
  8. php 安装swoole扩展
  9. 交互设计如何为业务赋能——谈谈网易严选企业采购的主页设计
  10. quartz mysql 表 集群配置_Quartz集群配置
  11. 通过自定义的key进行加密解密
  12. 生产工单收货控制增强
  13. TypeScript是什么,为什么要使用它?
  14. 英语六级语法:强调句,倒装句和虚拟语气
  15. Axure RP9 3675(软件+汉化包+Licenses)
  16. 2022-2027年中国公共图书馆资源行业发展监测及投资战略研究报告
  17. mysql 利用时间查询_利用时间的艺术
  18. oTree学习教程(一)概念性概述
  19. 机载雷达导论-学习笔记
  20. 评计算机中级职称上海积分,上海落户积分,这个中级职称(国家职业资格)性价比最高!...

热门文章

  1. 一博科技IPO破发:公司市值50亿 深圳南山区上市公司数达200家
  2. 前端css select、option禁用
  3. 求3个数的最小公倍数算法之数论进阶
  4. f1 六个矩形能否组成长方体(qsort,思路有理化,typedef struct的二项数组)
  5. 多个文件中如何共用一个全局变量
  6. Python实现将word的数据存入数据库
  7. python实现对比两个有增减的excel表格的不同并填充不同颜色
  8. JavaScript验证工具JSLint
  9. kbe之1分钟完成安装
  10. 苹果试玩基本操作技巧(入门篇)