【C++】【网络】【Linux系统编程】单例模式,加锁封装TCP/IP协议套接字
目录
引言
获取套接字
绑定套接字
表明允许监听
单例模式设计
完整代码示例
个人主页:东洛的克莱斯韦克-CSDN博客
引言
有关套接字编程的细节和更多的系统调用课参考《UNIX环境高级编程》一书,可以在如下网站搜索电子版,该书在第16章详细的介绍了各种接口。
Jiumo Search 鸠摩搜索 - 文档搜索引擎 (jiumodiary.com)
而在实际的编程中,总是用系统调用的接口难免会有些繁琐。我们可以根据自己的需求,用面向对象的思想封装出接口简洁的类。
也可以把类设计成单例,以组件的形式供上层使用。而上层坐拥下三层协议栈,无需关心网络通信的细节。
获取套接字
首先要用socket接口获取套接字文件描述符
int fd = socket(AF_INET, SOCK_STREAM, 0)
AF_INET表示IPv4因特网域
SOCK_STREAM表示该套接字的类型是全双工,面向字节流和链接的
第三个参数 0 表示根据前两个参数选择默认的协议,此时选择的就是TCP/IPv4协议栈
绑定套接字
bind(_socket_fd, (const struct sockaddr *)&address, (socklen_t)sizeof(address))
绑定套接字之前先用 struct sockaddr_in 结构体填充地址信息。
IPv4因特网域用struct sockaddr_in结构体填充,IPv6因特网域用struct sockaddr_in6结构体填充,为了使不同的地址格式能和套接字绑定,需要把对应的结构体强转成通用地址结构struct sockaddr。
struct sockaddr_in address;memset(&address, 0, sizeof(address)); // 把结构体初始化为0address.sin_family = AF_INET; // IPv4协议家族address.sin_addr.s_addr = INADDR_ANY; // 服务器选择任意IP地址接收请求address.sin_port = htons(_port); // 端口号信息,网络序列
填充字段时,需要用htons()函数把端口号改为网络字节序列。在填充之前最好初始化结构体。
INADDR_ANY表示套接字可以接收上层进程所在服务器的任意一个IP地址(公网IP),一台服务器可能会配置多个IP地址。
表明允许监听
listen(_socket_fd, 5)
第一个参数是网络文件描述符。
第二个参数提供了一个提示给系统,表明这个套接字所期望的、还未处理的(即还在等待被接受的连接)连接请求的最大队列长度。换句话说,它告诉系统内核为这个套接字分配多大的空间来存储尚未处理的连接请求。第二个参数不是严格遵守的。
单例模式设计
我们需要把类的构造函数,拷贝函数,赋值重载设为私有。在类似添加一个该类类型的指针,该指针是静态的并且是私有成员。
那么只给外面暴露一个获取该指针的接口,并且只能被获取一次。
获取指针的接口就需要加锁,防止并发问题。【Linux】用5万字满足你对线程的所有♥幻想♥——【线程概念】【线程安全】【多线程并发】【互斥量】【条件变量】【信号量】【锁的原理】【各种锁】【生产者消费者模型】【读者写者问题】-CSDN博客
完整代码示例
套接字代码已经在网络环境中测试过了~

日志代码
//日志打印
#pragma once
#include <iostream>
#include <string>
#include <ctime>
#define INFO 1
#define WARNING 2
#define ERROR 3
#define FATAL 4
#define LOG(level, message) Log(#level, message, __FILE__, __LINE__)void Log(std::string level, std::string message, std::string file_name, int line)
{std::cerr << "[" << level << "]" << "[" << time(nullptr) << "]" << "[" << message << "]" << "[" << file_name << "]" << "[" << line << "]" << std::endl;
}
套接字代码
#pragma once // 防止头文件被重复包含
#include <sys/socket.h>
#include <cstdlib>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <memory>
#include <pthread.h>
#include "log.hpp"#define BACKLOG 5 // 全连接队列最小值
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;class tcp_serve
{public:static tcp_serve *git_tcp_object(int port) // 获取单例实例{if (tcp_ptr == nullptr){pthread_mutex_lock(&mutex); // 加锁if (tcp_ptr == nullptr){tcp_ptr = new tcp_serve(port);tcp_ptr->initserve();}pthread_mutex_unlock(&mutex); // 解锁}return tcp_ptr;}int git_socket_fd(){return _socket_fd;}private:void initserve(){Socket();Bind();Listen();}tcp_serve(int port): _port(port), _socket_fd(-1){}~tcp_serve(){}tcp_serve(const tcp_serve &x);const tcp_serve &operator=(const tcp_serve &x);void Socket(){int fd = socket(AF_INET, SOCK_STREAM, 0); // 用IPv4协议家族,TCP协议if (-1 == fd){LOG(FATAL, "创建套接字失败");exit(1);} // 创建套接字失败_socket_fd = fd;LOG(INFO, "创建套接字成功");}void Bind(){struct sockaddr_in address;memset(&address, 0, sizeof(address)); // 把结构体初始化为0address.sin_family = AF_INET; // IPv4协议家族address.sin_addr.s_addr = INADDR_ANY; // 服务器选择任意IP地址接收请求address.sin_port = htons(_port); // 端口号信息,网络序列int opt = 1;if (setsockopt(_socket_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) < 0){LOG(WARNING, "端口不能在短时间内连续绑定");} // 防止TIME_WAIT状态导致绑定端口失败LOG(INFO, "端口复用设置成功");if (-1 == bind(_socket_fd, (const struct sockaddr *)&address, (socklen_t)sizeof(address))){LOG(FATAL, "绑定套接字失败");exit(2); // 绑定套接字失败}LOG(INFO, "套接字绑定成功");}void Listen(){if (-1 == listen(_socket_fd, BACKLOG)){LOG(FATAL, "声明自己可连接失败");exit(3);} // 请求链接失败LOG(INFO, "套接字允许监听链接");}private:int _port; // 端口int _socket_fd; // 套接字文件描述符static tcp_serve *tcp_ptr;
};tcp_serve *tcp_serve::tcp_ptr = nullptr;
相关文章:
【C++】【网络】【Linux系统编程】单例模式,加锁封装TCP/IP协议套接字
目录 引言 获取套接字 绑定套接字 表明允许监听 单例模式设计 完整代码示例 个人主页:东洛的克莱斯韦克-CSDN博客 引言 有关套接字编程的细节和更多的系统调用课参考《UNIX环境高级编程》一书,可以在如下网站搜索电子版,该书在第16章详…...
Matplotlib在运维开发中的应用
在现代运维开发中,数据可视化扮演着越来越重要的角色。它能帮助我们更直观地理解系统状态,快速发现潜在问题,并辅助决策制定。Python的Matplotlib库作为一个强大而灵活的绘图工具,在运维领域有着广泛的应用。本文将探讨Matplotlib在运维开发中的常见应用场景,并提供实用的代码示…...
centos下nvme over rdma 环境配置
nvme over rdma 环境配置 本文主要介绍NVMe over RDMA的安装和配置。关于什么是NVMe over Fabrics,什么是NVMe over RDMA,本文就不做介绍了,网上资料一大堆。 可以看看什么是NVMe over Fabrics? RDMA(全称:Remote Dir…...
【C++】——多态详解
目录 1、什么是多态? 2、多态的定义及实现 2.1多态的构成条件 2.2多态语法细节处理 2.3协变 2.4析构函数的重写 2.5C11 override 和 final关键字 2.6重载—重写—隐藏的对比分析 3、纯虚函数和抽象类 4、多态的原理分析 4.1多态是如何实现的 4.2虚函数…...
STM32上实现FFT算法精准测量正弦波信号的幅值、频率和相位差(标准库)
在研究声音、电力或任何形式的波形时,我们常常需要穿过表面看本质。FFT(快速傅里叶变换)就是这样一种强大的工具,它能够揭示隐藏在复杂信号背后的频率成分。本文将带你走进FFT的世界,了解它是如何将时域信号转化为频域…...
计算机毕业设计 农场投入品运营管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...
【笔记】2.1 半导体三极管(BJT,Bipolar Junction Transistor)
一、结构和符号 1. 三极管结构 常用的三极管的结构有硅平面管和锗合金管两种类型。各有PNP型和NPN型两种结构。 左图是NPN型硅平面三极管,右图是PNP型锗合金三极管。 从图中可见平面型三极管是先在一块大的金属板上注入杂质使之变成N型,然后再在中间注入杂质使之变成P型,…...
企业中文档团队的三种组织形式
大家好!今天咱们来聊聊企业里文档团队都是怎么组织的。 企业中,常见的文档团队组织形式有三种。 首先,最常见的就是集中式的文档团队。就是说,公司里头有几个不同的部门,每个部门都需要做文档。于是呢,公…...
古诗词四首鉴赏
1、出自蓟北门行 唐李白 虏阵横北荒,胡星曜精芒。 羽书速惊电,烽火昼连光。 虎竹救边急,戎车森已行。 明主不安席,按剑心飞扬。 推毂出猛将,连旗登战场。 兵威冲绝漠,杀气凌穹苍。…...
全国行政区划下载(高德、阿里、天地图)
一、网站链接: 阿里云数据可视化平台: DataV.GeoAtlas地理小工具系列 (aliyun.com) 链接: link 高德地图API获取行政区域: 高德地图API获取行政区域 (naivemap.com) 链接: link 天地图服务中心: 天地图 服务中心 (tianditu.g…...
Springboot提升-MapStruct组件使用
文章目录 1. 添加依赖2. 创建映射接口3. 在Spring Boot中使用MapStruct映射器4. 配置MapStruct 在Spring Boot项目中使用MapStruct可以帮助你更方便地管理对象之间的映射逻辑。下面是一些基本步骤来设置和使用MapStruct: 1. 添加依赖 首先,你需要在项目…...
如何借助ChatGPT提升论文质量:实战指南
在学术写作的过程中,非英语母语人士经常面临诸多挑战,尤其是当论文要提交给国际期刊时,语言规范和表达逻辑成为了必须克服的障碍。本文将通过实例详细解析如何利用ChatGPT来润色论文,使其达到发表级别的标准。 一、优秀学术论文的写作特点 要让学术论文在国际期刊上发表,…...
NLP开端:Tokenizer-文本向量化
Tokenizer 问题背景 An was a algorithm engineer 如上所示,在自然语言处理任务中,通常输入处理的数据是原始文本。但是算法模型自能处理数值类型,因此需要找到一种方法,将原始的文本数据转换为数值类型的数据。这就是分词器所…...
STM32 MCU学习资源
STM32 MCU学习资源 文档下载需要注册登录账号 ST公司官方文档 STM32 MCU开发者资源 STM32F446 相关PDF文档 ST中文论坛 中文译文资料 ST MCU中文官网 其他学习资源 野火STM32库开发实战指南 零基础快速上手STM32开发(手把手保姆级教程) 直接使…...
Python知识点:Python内存管理与优化
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! Python内存管理与优化指南 Python是一种动态类型的解释型语言,它提…...
SpringBoot Kafka发送消息与接收消息实例
前言 Kafka的基本工作原理 我们将消息的发布(publish)称作 producer(生产者),将消息的订阅(subscribe)表述为 consumer(消费者),将中间的存储阵列称作 broker(代理),这…...
【资料分析】刷题日记2
第一套 √ 2013-2016一共有13,14,15,16四年,亦即16 - 13 1 4年 √ 是多少倍 ③vs④:都是只给出了年均增速,③求的是其中一年的,无法确定;④求的是这个时段总共的,可…...
Aigtek功率放大器怎么选择型号
功率放大器在各个领域中都扮演着重要的角色,用于增强信号的幅度,以满足特定的需求。在选择功率放大器型号时,需要综合考虑多个因素,如应用领域、功率要求、频率范围、输入输出特性等。下面安泰电子官网将从这些方面详细介绍功率放…...
【RabbitMQ】重试机制、TTL
重试机制 在消息从Broker到消费者的传递过程中,可能会遇到各种问题,如网络故障、服务不可用、资源不足等,这些问题都可能导致消息处理失败。为了解决这些问题,RabbitMQ提供了重试机制,允许消息在处理失败之后重新发送…...
Linux用户及用户组操作命令笔记
1.用户概念及作用 用户:指的是Linux操作系统中用于管理系统或者服务的人 Linux下一切皆文件,所以用户管理的是相应的文件 基本上分为两种: 基本管理:文件的创建、删除、复制、查找、打包压缩等;文件的权限增加、减…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
