【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下一切皆文件,所以用户管理的是相应的文件 基本上分为两种: 基本管理:文件的创建、删除、复制、查找、打包压缩等;文件的权限增加、减…...
别再手动翻GitHub了!用Crawl4AI自动抓取AI开源项目(附Python配置避坑指南)
用Crawl4AI打造你的AI开源情报系统:从零配置到自动化实战 每次在GitHub上手动搜索AI项目时,你是否也经历过这样的困境?输入"machine learning"得到的结果里混杂着十年前的教学代码,筛选"deep learning"标签后…...
3步彻底解决显卡驱动残留:Display Driver Uninstaller深度应用指南
3步彻底解决显卡驱动残留:Display Driver Uninstaller深度应用指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-…...
抖音批量下载工具终极指南:如何高效无水印下载视频内容
抖音批量下载工具终极指南:如何高效无水印下载视频内容 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback supp…...
Granite-4.0-H-350M在数学建模竞赛中的应用:算法优化
Granite-4.0-H-350M在数学建模竞赛中的应用:算法优化 1. 数学建模竞赛中的真实痛点 数学建模竞赛对参赛者来说从来都不是轻松的任务。从拿到题目到提交最终报告,通常只有短短几天时间,而在这有限的时间里,团队需要完成问题理解、…...
HunyuanVideo-Foley快速部署:从拉取镜像到生成首段音效仅需8分钟
HunyuanVideo-Foley快速部署:从拉取镜像到生成首段音效仅需8分钟 1. 环境准备与镜像拉取 在开始之前,请确保您的硬件配置满足以下要求: 显卡:NVIDIA RTX 4090/4090D 24GB显存内存:至少120GBCPU:10核及以…...
Wan2.2-I2V-A14B实际作品分享:电商广告/短视频/教学素材生成案例
Wan2.2-I2V-A14B实际作品分享:电商广告/短视频/教学素材生成案例 1. 开篇:认识Wan2.2-I2V-A14B视频生成能力 Wan2.2-I2V-A14B是一款强大的文生视频模型,能够根据文字描述生成高质量的视频内容。经过私有部署镜像的深度优化,这款…...
(六)openEuler欧拉系统LVM动态扩容实战:从规划到文件系统在线扩展
1. 为什么需要动态扩容? 最近接手了一个跑在openEuler上的业务系统,数据量每天都在疯涨。上周监控突然报警,根目录只剩下10%的空间,眼看着就要撑爆了。这种情况要是放在以前,估计得停机扩容,但现在有了LVM&…...
华为eNSP实战:3种方法搞定VLAN间通信(附完整配置命令)
华为eNSP实战:VLAN间通信的3种工程化解决方案深度解析 刚接触企业级网络时,最让我困惑的就是不同部门间的网络隔离与互通问题。财务部的电脑为什么不能直接访问研发部的服务器?为什么同一个物理交换机下的设备会被划分到不同的广播域…...
从漏洞复现到修复:手把手教你用ModHeader测试和防御HTTP Host头攻击
HTTP Host头攻击实战:从漏洞复现到Nginx防御全解析 当你在浏览器地址栏输入一个网址时,很少有人会注意到背后那个看似普通的Host头字段。正是这个不起眼的HTTP头部,却可能成为攻击者撬开系统大门的杠杆。想象一下,攻击者只需修改这…...
ModelScope API 新手必看:从申请Key到调用Qwen3-32B模型的完整流程
ModelScope API 新手必看:从申请Key到调用Qwen3-32B模型的完整流程 第一次接触ModelScope API时,我花了整整两天时间才搞明白整个流程。不是文档不够详细,而是实际操作中总会遇到各种意想不到的小问题。本文将带你避开这些坑,从零…...
