1.5.C++项目:仿muduo库实现并发服务器之socket模块的设计
项目完整版在:
一、socket模块:套接字模块

二、提供的功能
Socket模块是对套接字操作封装的一个模块,主要实现的socket的各项操作。
socket 模块:套接字的功能
创建套接字
绑定地址信息
开始监听
向服务器发起连接
获取新连接
接受数据
发送数据
关闭套接字
创建一个监听链接
创建一个客户端连接
设置套接字选项——开启地址端口重用!
设置套接字阻塞属性——设置为非阻塞!
三、实现思想
(一)功能
对socket套接字的操作进行封装。
(二)意义
对socket套接字的操作进行封装。
(三)功能设计
- 创建套接字
- 绑定地址信息
- 开始监听
- 向服务器发起连接
- 获取新连接
- 接受数据
- 发送数据
- 关闭套接字
- 创建一个监听链接
- 创建一个客户端连接
四、代码
#define MAX_LISTEN 1024
class Socket {private:int _sockfd;public:Socket() :_sockfd(-1) {}Socket(int fd) : _sockfd(fd) {} ~Socket() {Close(); }int fd() {return _sockfd;}// 1.创建套接字bool Create() {//int socket (int domain,int type,int protocol);_sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if (_sockfd < 0) {ERR_LOG("CREATE SOCKET FAILED !!");return false;}return true;} // 2.绑定地址信息bool Bind(const std::string &ip,uint16_t port) {struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);// int bind(int sockfd,struct sockaddr * addr,socklen_t len);int ret = bind(_sockfd,(struct sockaddr*)&addr,len);if (ret < 0) {ERR_LOG("BIND ADDRESS FAILED!!!!");return false;}return true;}// 3.开始监听bool Listen(int backlog = MAX_LISTEN) {// int listen(int backlog)int ret = listen(_sockfd,backlog);if (ret < 0) {ERR_LOG("SOCKET LISTEN FAILED!!");return false;}return true;}// 4. 向服务器发起连接bool Connect(const std:: string& ip,uint16_t port) {struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);// int bind(int sockfd,struct sockaddr * addr,socklen_t len);int ret = connect(_sockfd,(struct sockaddr*)&addr,len);if (ret < 0) {ERR_LOG("CONNECT ADDRESS FAILED!!!!");return false;}return true;} // 5. 获取新连接int Accept() {// int accept(int sockfd,struct sockaddr* addr,socklen_t *len) /int newfd = accept(_sockfd,NULL,NULL);if (newfd < 0) {ERR_LOG("SOCKET ACCEPT FAILED!!!!");return false;}return newfd;}ssize_t Recv(void *buf,size_t len,int flag = 0){// 6.接收数据//有符号长整型 //ssize_t Recv(int sockfd,void* buf,size_t len,int flag);ssize_t ret = recv(_sockfd,buf,len,flag);if (ret <= 0) {// EAGAIN 当前socket的接收缓冲区没有数据来,在非阻塞二点情况下才会有这个错误// ENTER 当前socket的阻塞等待,被信号打断了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); // MSG_DONTWAIT 表示当前接受为非阻塞}// 7.发送数据ssize_t Send(const void* buf,size_t len,int flag = 0) {// ssize_t send(int sockfd,void *data,size_t len,int flag) ssize_t ret = send(_sockfd,buf,len,flag);if (ret < 0) {ERR_LOG("SOCKET SEND FAILED!!");return -1; // 出错}return ret; // 实际发送数据长度!!}ssize_t nonBlockSend(void* buf,size_t len) {return Send(buf,len,MSG_DONTWAIT); // MSG_DONTWAIT 表示当前接受为非阻塞}// 8.关闭套接字void Close() {if (_sockfd != -1) {close(_sockfd);_sockfd = -1;}}// 9.创建一个服务端链接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 (Bind(ip,port) == false) return false;if (Listen() == false) return false;if (block_flag) NonBlock();ReuseAddress();return true;}// 10.创建一个客户端链接 bool createClient(uint16_t port, const std::string &ip) {if (Create() == false) return false;if (Connect(ip,port) == false) return false;return true;}// 11. 设置套接字选项——开启地址端口重用!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;setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void*)&val, sizeof(int));}// 12. 设置套接字阻塞属性——设置为非阻塞! void NonBlock() {int flag = fcntl(_sockfd, F_GETFL, 0);fcntl(_sockfd, F_SETFL, flag | O_NONBLOCK);}};
五、测试
(一)tcp_cli.cc
#include "../source/server.hpp"int main() {Socket cli_sock;cli_sock.createClient(8500,"127.0.0.1");std::string str = "nihao";cli_sock.Send(str.c_str(),str.size());char buf[1024] = {0};cli_sock.Recv(buf,1023);DBG_LOG("%s",buf);return 0;
}
(二)tcp_srv.cc
#include "../source/server.hpp"int main() {Socket lst_sock;bool ret = lst_sock.createServer(8500);while (1) {int newfd = lst_sock.Accept();if (newfd < 0) {continue;}Socket cli_sock(newfd);char buf[1024] = {0};int ret = cli_sock.Recv(buf,1023);if(ret < 0) {cli_sock.Close();}cli_sock.Send(buf,ret);cli_sock.Close();}lst_sock.Close();return 0;
}
(三)makefile
all:client server
client:tcp_cli.ccg++ -std=c++11 $^ -o $@
server:tcp_srv.ccg++ -std=c++11 $^ -o $@
相关文章:
1.5.C++项目:仿muduo库实现并发服务器之socket模块的设计
项目完整版在: 一、socket模块:套接字模块 二、提供的功能 Socket模块是对套接字操作封装的一个模块,主要实现的socket的各项操作。 socket 模块:套接字的功能 创建套接字 绑定地址信息 开始监听 向服务器发起连接 获取新连接 …...
whisper+剪映+chatgpt实现实时语音对话功能
whisper将录音文件转成文字---chatgpt回答---剪映tts将文字转成语言。 GitHub - openai/whisper: Robust Speech Recognition via Large-Scale Weak Supervision whisper剪映chatgpt实现实时语音对话功能_哔哩哔哩_bilibili...
ASUS华硕ZenBook 13灵耀U 2代U3300F笔记本UX333FN/FA原装出厂Win10系统工厂安装模式
系统自带所有驱动、出厂主题壁纸、系统属性华硕专属LOGO标志、Office办公软件、MyASUS华硕电脑管家等预装程序 下载链接:https://pan.baidu.com/s/1dK0vMZMECPlT63Rb6-jeFg?pwdbym5 所需要工具:16G或以上的U盘(非必需) 文件格式:HDI,SWP,O…...
前端面试的话术集锦第 21 篇博文——高频考点(设计模式)
这是记录前端面试的话术集锦第二十一篇博文——高频考点(设计模式),我会不断更新该博文。❗❗❗ 设计模式总的来说是一个抽象的概念,前人通过无数次的实践总结出的一套写代码的方式,通过这种方式写的代码可以让别人更加容易阅读、维护以及复用。 这一章节我们将来学习几…...
php实战案例记录(2)生成包含字母和数字但不重复的用户名
在PHP中,您可以使用以下代码生成不重复的10个用户名,每个用户名包含英文字母和数字: $generatedUsernames array(); // 存储生成的用户名while (count($generatedUsernames) < 10) {$username generateUsername();if (!in_array($usern…...
分类预测 | Matlab实现SSA-CNN-SVM麻雀算法优化卷积支持向量机分类预测
分类预测 | Matlab实现SSA-CNN-SVM麻雀算法优化卷积支持向量机分类预测 目录 分类预测 | Matlab实现SSA-CNN-SVM麻雀算法优化卷积支持向量机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现SSA-CNN-SVM麻雀算法优化卷积支持向量机分类预测࿰…...
【ARMv8 SIMD和浮点指令编程】NEON 加载指令——如何将数据从内存搬到寄存器(其它指令)?
除了基础的 LDx 指令,还有 LDP、LDR 这些指令,我们也需要关注。 1 LDNP (SIMD&FP) 加载 SIMD&FP 寄存器对,带有非临时提示。该指令从内存加载一对 SIMD&FP 寄存器,向内存系统发出访问是非临时的提示。用于加载的地址是根据基址寄存器值和可选的立即偏移量计算…...
ElementPlus· tab切换/标签切换 + 分页
tab切换 ---> <el-tabs><el-tab-pane>... 分页 --------> <el-pagination> tab切换 // tab标签切换 // v-model双向绑定选项中的name,tab-change事件在 activeName改变时触发 <script setup> const tabChange (tab, event)>{…...
华为云云耀云服务器L实例评测|搭建CounterStrike Source Delicated Server(CS起源游戏服务器)
华为云云耀云服务器L实例评测|搭建CounterStrike Source Delicated Server(CS起源游戏服务器) #【有奖征文】华为云云服务器焕新上线,快来亲身感受评测吧!# ⭐️ CounterStrikeSource(CS起源是Valve的一款…...
腾讯云中使用ubuntu安装属于自己的overleaf
在自己的云服务器上安装overleaf的需求是从写论文开始的,总担心自己的论文放在一个网站上被泄露,所以想要在自己的服务器上安装自己的overleaf,正好手边有一个云服务器,现在开始。 配置腾讯云 因为使用overleaf的优势就是在不同…...
【redisson学习笔记】
1)clone项目 git clone https://github.com/redisson/redisson.git本来想直接用maven编译源码, 却发现各种错误,主要是maven的编译插件版本问题。 2)然后用maven包方式引入 <dependencies><dependency><groupId>org.redisson</gr…...
gurobi属性篇一
1.构造目标函数 (1)一般的写法: 我们常见的目标函数写法通常是定义好式子zf(x,y,...),然后用m.setObjective(z, GRB。MINIMIZE),这样的定义方式比较普遍。 这也是一般的写法。 (2)但还有一种写法…...
【python数据建模】Pandas库
概述 Pandas库主要提供了三种数据结构: (1)Series:带标签的一维数据 (2)DataFrame:带标签且大小可变的二维表结构 (3)Panel:带标签且大小可变的三维数据 Pan…...
Flutter笔记:关于应用程序中提交图片作为头像
Flutter笔记 关于应用程序中提交图片作为头像 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/133418554…...
【C++】C++的类型转换
文章目录 1. C语言中的类型转换2. C中的类型转换2.1 static_cast2.2 reinterpret_cast2.3 const_cast2.4 dynamic 1. C语言中的类型转换 在C语言中,经常会出现一种情况:运算符两边的类型不同,或者形参实参类型不匹配,此时就会发生…...
ahk系列——ahk_v2实现win10任意界面ocr
前言: 不依赖外部api接口,界面简洁,翻译快速,操作简单, 有网络就能用 、还可以把ocr结果非中文翻译成中文、同样可以识别中英日韩等60多个国家语言并翻译成中文,十分的nice 1、所需环境 windows10及其以上…...
linux下端口映射
linux下端口映射 1. 允许数据包转发 echo 1 >/proc/sys/net/ipv4/ip_forwardiptables -t nat -A POSTROUTING -j MASQUERADEiptables -A FORWARD -i [内网网卡名称] -j ACCEPTiptables -t nat -A POSTROUTING -s [内网网段] -o [外网网卡名称] -j MASQUERADE# 例:…...
C++ 迭代器(iterator)
迭代器介绍 迭代器(iterator):容器类型内置的“指针” - 使用迭代器可以访问某个元素,迭代器也能从一个元素移动到另一个元素。 - 有迭代器的类型都拥有 begin 和 end 成员- begin:返回指向第一个元素(或字…...
基于Python3搭建qt开发环境
Python可视化编程相信大部分刚接触都是tkinter,tkinter是Python自带的库,不需要安装第三方库即可使用,在我的Python专栏中也有很多基于tkinter来设计的可视化界面。本篇文章将尝试另外一个Python的可视化编程库(pyqt),与tkinter编…...
Linux常见操作命令(1)
前言:作者也是初学Linux,可能总结的还不是很到位 ♈️今日夜电波:达尔文—林俊杰 0:30━━━━━━️💟──────── 4:06 🔄 ◀️ …...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
