当前位置: 首页 > news >正文

C++仿mudo库高并发服务器项目:Socket模块

前言

本篇文章所讲的是本人的个人项目仿muduo库高并发服务器中的Socket模块实现部分。

Socket模块介绍:

Socket模块是对套接字操作封装的⼀个模块,主要实现的socket的各项操作。

  • 功能:对socket套接字的操作进行封装

  • 意义:在接下来的开发中,使我们对于套接字的各项操作更加简便,避免代码冗余

  • 功能设计:

    1. 创建套接字

    2. 绑定地址信息

    3. 开始监听

    4. 向服务器发起连接

    5. 获取新连接

    6. 接收数据

    7. 发送数据

    8. 关闭套接字

    9. 创建一个监听连接

    10. 创建一个客户端连接

    关于对套接字操作的函数socket,bind,listen,accept等想更深入了解的,可以看我这篇博客:

    Linux下简单的TCP服务器

代码实现:

const int MAX_LISTEN = 1024;
class Socket
{
private:int _sockfd;
public:Socket():_sockfd(-1){}Socket(int fd):_sockfd(fd){}~Socket(){Close();}int Fd(){return _sockfd;}//创建套接字bool Create(){//int socket(int domain,int type,int protocol)//ipv4 字节流 TCP_sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(_sockfd < 0){ERR_LOG("CREATE SOCKET FAILED!!");return false;}return true;}//绑定地址信息bool Bind(const std::string& ip,uint16_t port){//ipv4专用地址struct sockaddr_in addr;addr.sin_family = AF_INET;//将点分十进制ip地址转换为网络字节序(大端)                              //ipv4addr.sin_addr.s_addr = inet_addr(ip.c_str());//记得主机转网络序列addr.sin_port = htons(port);socklen_t len = sizeof(struct sockaddr_in);//bind时转换为通用协议地址int ret = bind(_sockfd,(struct sockaddr*)&addr,len);if(ret < 0){ERR_LOG("BIND ADDRESS FAILED!!");return false;}return true;}//开始监听 bool Listen(int backlog = MAX_LISTEN){int ret = listen(_sockfd,backlog);if(ret < 0){ERR_LOG("SOCKET LISTEN FAILED!!");return false;}return true;}//向服务器发起连接bool Connect(const std::string& ip,uint16_t port){struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ip.c_str());addr.sin_port = htons(port);socklen_t len = sizeof(struct sockaddr_in);int ret = connect(_sockfd,(struct sockaddr*)&addr,len);if(ret < 0){ERR_LOG("CONNECT SERVER FAILED!!");return false;}return true;}//获取新连接int Accept(){   //不关心客户端,后两个参数设为空int newfd = accept(_sockfd,nullptr,nullptr);if(newfd < 0){ERR_LOG("SOCKET ACCEPT FAILED!!");return -1;}return newfd;}//接收数据ssize_t Recv(void* buf,size_t len,int flag = 0){ssize_t ret = recv(_sockfd,buf,len,flag);//ret == 0 连接断开if(ret <= 0){//EAGAIN,没有数据,非阻塞模式才会出现这个错误//EINTR,阻塞等待时被打断if(errno == EAGAIN || errno == EINTR){return 0;//这次没有收到数据}ERR_LOG("SOCKET RECV FAILED!!");return -1;}return ret;//返回实际接收长度}ssize_t NonBlockRecv(void* buf,size_t len){return Recv(buf,len,MSG_DONTWAIT);//非阻塞模式}//发送数据ssize_t Send(const void* buf,size_t len,int flag = 0){ssize_t ret = send(_sockfd,buf,len,flag);if(ret < 0){if(errno == EAGAIN || errno == EINTR){return 0;}ERR_LOG("SOCKET SEND FAILED!!");return -1;}return ret;//实际发送长度}ssize_t NonBlockSend(const void* buf,size_t len){return Send(buf,len,MSG_DONTWAIT);}//关闭套接字void Close(){if(_sockfd != -1){close(_sockfd);_sockfd = -1;}}//创建一个服务器连接bool CreateServer(uint16_t port,const std::string& ip = "0.0.0.0",bool block_flag = false){//1.创建套接字 2.设置非阻塞 3.设置地址重用 4.绑定地址 5.开始监听if(Create() == false) return false;if(block_flag) Nonblock();//绑定前开启地址重用ReuseAddress();if(Bind(ip,port) == false) return false;if(Listen() == false) return false;return true;}//创建一个客户端连接bool CreateClient(uint16_t port,const std::string& ip){//1.创建套接字 2.连接服务器if(Create() == false) return false;if(Connect(ip,port) == false) return false;return true;}//设置套接字选项,开启地址端口重用void ReuseAddress(){// int setsockopt(int fd, int leve, int optname, void *val, int vallen)int val = 1;//开启地址端口重用setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR,(void*)&val,sizeof(int));val = 1;//允许多个进程绑定相同ip+端口setsockopt(_sockfd,SOL_SOCKET,SO_REUSEPORT,(void*)&val,sizeof(int));}//设置套接字属性,设置为非阻塞void Nonblock(){//int fcntl(int fd, int cmd, ... /* arg */ );int flag = fcntl(_sockfd,F_GETFL,0);fcntl(_sockfd,F_SETFL,flag | O_NONBLOCK);}
};
http://www.dtcms.com/a/520159.html

相关文章:

  • 找人帮忙做网站吉林市百姓网免费发布信息网
  • HTTP与HTTPS协议区别及应用场景
  • HTTP 206状态码:部分内容传输核心技术
  • Vue3 -- 第一个vue项目
  • 收钱码合并的网站怎么做电商网站产品模块
  • Vitis HLS 学习指南与实践教程
  • FBH公司开发了200 MHz GaN降压变换器模块
  • SpiderDemo题解系列——第3篇:调试拦截与非对称加密挑战 — JS逆向调试实战(第23题)
  • 机器学习之数字识别
  • 网站开发群安阳网站设计多少钱
  • 7. Prometheus告警配置-alertmanger
  • 自动签到之实现掘金模拟签到
  • 【探寻C++之旅】C++11 深度解析:重塑现代 C++ 的关键特性
  • 【unity】运行时加载并修改ScriptableObject类型资源对象的值会怎样
  • Spring Boot 实现 DOCX 转 PDF(基于 docx4j 的轻量级开源方案)
  • 服装企业官方网站建设网站运营收入
  • Spring Boot Actuator深度解析与实战
  • 如何做 行业社交类网站网站 建设在作用
  • 线程3 JavaEE(阻塞队列,线程池)
  • K8s中,deployment 是如何从 yaml 文件最终部署成功 pod 的
  • RK3588 使用 FFmpeg 硬件解码输出到 DRM Prime (DMA Buf) 加速数据传输
  • 基于蚁群算法的PID参数整定方法及MATLAB实现
  • 排序算法大全——插入排序
  • 手搓一个CUDA JIT编译器
  • 网站引导页模板互联网公司排名全球
  • JDK 9 List.of(...)
  • 做一个vue3 v-model 双向绑定的弹窗
  • 为超过10亿条记录的订单表新增字段
  • 哪里做网站最便宜WordPress功能模块排版
  • 每日算法刷题Day78:10.23:leetcode 一般树7道题,用时1h30min