【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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1536905.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

杨氏矩阵中查找想要找到的数

文章目录 一、题目二、思路三、代码实现 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、题目 二、思路 第一步 根据杨氏矩阵的规则说明矩阵从左到右递增&#xff0c;从上往下递增&#xff0c;因此我们可以画出这样的图。 对于杨氏矩阵&#xff0…

FPGA与Matlab图像处理之直方图均衡化

文章目录 一、什么是直方图?二、什么是直方图均衡化&#xff1f;三、Matlab实现直方图均衡化的步骤第一步&#xff1a; 彩色图像转成灰度图像第二步&#xff1a;提取亮度通道的直方图第三步&#xff1a;累计亮度通道的像素值频率第四步&#xff1a; 映射到新的灰度值 四、Veri…

10.2高斯金字塔-向上取样

实验原理 在OpenCV中&#xff0c;高斯金字塔&#xff08;Gaussian Pyramid&#xff09;和上采样&#xff08;Upsampling&#xff09;是图像处理中的常见技术&#xff0c;它们经常用于图像的多分辨率分析。高斯金字塔主要用于图像的多尺度表示&#xff0c;而上采样则是将图像放…

Porcupine - 语音关键词唤醒引擎

文章目录 一、关于 Porcupine特点用例尝试一下 语言支持性能 二、Demo1、Python Demo2、iOS DemoBackgroundService DemoForegroundApp Demo 3、网页 Demo3.1 Vanilla JavaScript 和 HTML3.2 Vue Demos 三、SDK - Python 一、关于 Porcupine Porcupine 是一个高度准确和轻量级…

数据结构之线性表(python)

华子目录 线性表的定义前驱与后继 1.顺序表&#xff08;顺序存储结构&#xff09;python列表与数组的区别列表数组 1.1插入数据实例 1.2删除元素实例 1.3查找元素1.4修改元素1.5综合示例 2.单链表2.1单链表的初始化2.2插入元素示例注意 2.3删除元素示例 2.4修改元素2.5查找元素…

图解Self-Attention和代码实现,大语言模型基础思维导图

文章目录 1 Self-Attention的概念注意优缺点 2 Self-Attention的原理Q,K,V, and Self-Attention计算公式代码实现 Self-Attention的计算细节输入是如何Embedding的&#xff1f;Word EmbeddingsSentence EmbeddingsPre-trained Embeddings SelfAttention是如何计算的计算图 4 Se…

无畏契约 (Valorant)YOLO 模型数据集

4万数据集 无畏契约 Valorant YOLO 模型 数据集 截图大小&#xff1a;256x256 截图数量&#xff1a;40000包含保安拌线&#xff0c;被闪被黑&#xff0c;蝰蛇大招内 模型类别&#xff1a;2类 头身类 1身0头 人物&#xff1a;黄色色盲 已添加部分负样本&#xff0c;防止识别除敌…

数据结构——“二叉搜索树”

二叉搜索树是一个很重要的数据结构&#xff0c;它的特殊结构可以在很短的时间复杂度找到我们想要的数据。最坏情况下的时间复杂度是O(n)&#xff0c;最好是O(logn)。接下来看一看它的接口函数的实现。 为了使用方便&#xff0c;这里采用模版的方式&#xff1a; 一、节点 temp…

docker部署Stirling-PDF

github网址&#xff1a; GitHub - Stirling-Tools/Stirling-PDF: #1 Locally hosted web application that allows you to perform various operations on PDF files 1、官方docker镜像无法拉取&#xff0c;使用别人阿里云私人镜像仓库下载Stirling-PDF镜像&#xff1a; regi…

微服务以及注册中心

一、什么是微服务 微服务是指开发一个单个小型的但有业务功能的服务&#xff0c;每个服务都有自己的处理和轻量通讯机制&#xff0c;可以部署在单个或多个服务器上。微服务也指一种松耦合的、有一定的有界上下文的面向服务架构。也就是说&#xff0c;如果每个服务都要同时修改…

Objects as Points基于中心点的目标检测方法CenterNet—CVPR2019

Anchor Free目标检测算法—CenterNet Objects as Points论文解析 Anchor Free和Anchor Base方法的区别在于是否在检测的过程中生成大量的先验框。CenterNet直接预测物体的中心点的位置坐标。 CenterNet本质上类似于一种关键点的识别。识别的是物体的中心点位置。 有了中心点之…

AI助力遥感影像智能分析计算,基于高精度YOLOv5全系列参数【n/s/m/l/x】模型开发构建卫星遥感拍摄场景下地面建筑物智能化分割检测识别系统

随着科技的飞速发展&#xff0c;卫星遥感技术已成为获取地球表面信息的重要手段之一。卫星遥感图像以其覆盖范围广、数据量大、信息丰富等特点&#xff0c;在环境监测、城市规划、灾害评估等多个领域发挥着不可替代的作用。然而&#xff0c;面对海量的卫星图像数据&#xff0c;…

wx小程序渗透思路

免责声明:本文仅做分享! 目录 WX小程序源代码 wx小程序目录位置: 反编译: e0e1-wx.py工具 unveilr.exe工具 查看源代码: 微信开发者工具: WX抓包 Fiddler抓包 官网下载 下载证书 操作: bp proxifier bp:(代理抓包) proxifier:(本地代理) WX小程序源代码 其实就…

程序修改题(41-50)

第四十一题 题目 给定程序modi1.c的主函数中&#xff0c;将a、b、c三个结点链成一个单向链表&#xff0c;并给各结点的数据域赋值&#xff0c;函数fun()的作用是:累加链表结点数据域中的数据作为函数值返回。 #include <stdio.h> typedef struct list { int data…

【数据结构-扫描线】力扣57. 插入区间

给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval [start, end] 表示另一个区间的开始和…

李宏毅结构化学习 02

文章目录 一、上篇博文复习二、Separable Case三、Non-separable Case四、Considering Errors五、Regularization六、Structured SVM七、Cutting Plane Algorithm for Structured SVM八、Multi-class and binary SVM九、Beyond Structured SVM 一、上篇博文复习 图中x表示输入的…

Android Framework(六)WMS-窗口显示流程——窗口内容绘制与显示

文章目录 窗口显示流程明确目标 窗户内容绘制与显示流程窗口Surface状态完整流程图 应用端处理finishDrawingWindow 的触发 system_service处理WindowState状态 -- COMMIT_DRAW_PENDING本次layout 流程简述 窗口显示流程 目前窗口的显示到了最后一步。 在 addWindow 流程中&…

基于Python的自然语言处理系列(10):使用双向LSTM进行文本分类

在前一篇文章中&#xff0c;我们介绍了如何使用RNN进行文本分类。在这篇文章中&#xff0c;我们将进一步优化模型&#xff0c;使用双向多层LSTM来替代RNN&#xff0c;从而提高模型在序列数据上的表现。LSTM通过引入一个额外的记忆单元&#xff08;cell state&#xff09;来解决…

24.Redis实现全局唯一ID

是一种分布式系统下用来生成全局唯一ID的工具。 特点 1.唯一性 2.高可用 3.高性能 4.递增性&#xff0c;数据也要保持一种递增&#xff0c;有利于数据库进行查询。 5.安全性 全局唯一ID的生成策略 1.UUID(没有顺序&#xff0c;字符串类型&#xff0c;效率不高) 2.Redis…

【电路笔记】-差分运算放大器

差分运算放大器 文章目录 差分运算放大器1、概述2、差分运算放大器表示2.1 差分模式2.2 减法器模式3、差分放大器示例3.1 相关电阻3.2 惠斯通桥3.3 光/温度检测4、仪表放大器5、总结1、概述 在之前的文章中,我们讨论了反相运算放大器和同相运算放大器,我们考虑了在运算放大器…