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

C++套接字库sockpp介绍

      sockpp是一个开源、简单、现代的C++套接字库,地址为:https://github.com/fpagliughi/sockpp,最新发布版本为0.8.1,license为BSD-3-Clause。目前支持Linux、Windows、Mac上的IPv4、IPv6和Unix域套接字。其它*nix和POSIX系统只需很少的修改或无需修改即可工作。
      1.套接字基类包装(wrap)系统套接字句柄,并维持其生命周期。当C++对象超出范围时,它会关闭底层套接字句柄。套接字对象通常是可移动的,但不可复制。可以使用 std::move()将套接字从一个作用域(或线程)传输到另一个作用域。
      2.库中的所有代码都位于sockpp C++命名空间内。
      3.TCP和其它"流"网络应用程序通常设置为服务器或客户端。接受器用于创建TCP/流服务器。它绑定一个地址并侦听已知端口以接受传入连接。 当连接被接受时,会创建一个新的流式套接字。该新套接字可以直接处理或移动到线程(或线程池)进行处理。
      相反,要创建TCP客户端,需要创建连接器对象并将其连接到已知地址(通常是主机和套接字)的服务器。连接后,套接字是一种流式套接字,可以直接用于读写。
      对于IPv4,sockpp::tcp_acceptor和sockpp::tcp_connector类分别用于创建服务器和客户端。它们使用sockpp::inet_address类来指定由32位主机地址和16位端口号组成的端点地址。
      sockpp::tcp_acceptor通常位于一个循环中接受新连接,并将它们传递给另一个进程、线程或线程池以与客户端交互
      TCP客户端稍微简单一些,创建一个sockpp::tcp_connector对象并连接,然后可以直接读写数据。
      4.每个套接字类的默认构造函数不执行任何操作,只是将底层句柄设置为INVALID_SOCKET。它们不创建套接字对象。
      5.套接字对象不是线程安全的。想要有多个线程从套接字读取或写入套接字的应用程序应该使用某种形式的序列化,例如std::mutex来保护访问。套接字可以安全地从一个线程移动到(moved)另一个线程。这是服务器的一种常见模式,它使用一个线程接受传入连接,然后将新套接字传递给另一个线程或线程池进行处理。
      由于套接字无法复制,唯一的选择是将套接字移动到这样的函数。这是一种常见的模式,尤其是在客户端应用程序中,让一个线程从套接字读取数据,另一个线程向套接字写入数据。在这种情况下,底层套接字句柄可以被认为是线程安全的(一个读线程和一个写线程)。但即使在这种情况下,sockpp::socket对象仍然不是线程安全的,特别是由于缓存的错误值(cached error value)。写入线程可能会看到读取线程上发生的错误,反之亦然。
      这种情况的解决方案是使用socket::clone()方法来复制套接字。这将使用系统的dup()函数或类似的函数创建另一个带有套接字句柄的重复副本的套接字。这样做的另一个好处是套接字的每个副本都可以保持独立的生命周期。在两个对象超出范围之前,底层套接字不会关闭。

      在Windows和Linux上编译的sockpp的shell脚本如下:

#! /bin/bashif [ $# != 2 ]; thenecho "Error: requires two parameters: 1: windows or linux; 2: release or debug"echo "For example: $0 windows debug"exit -1
fiif [ $1 != "windows"  ] && [ $1 != "linux" ]; thenecho "Error: the first parameter can only be windows or linux"exit -1
fiif [ $2 != "debug" ] && [ $2 != "release" ]; thenecho "Error: the second parameter can only be debug or release"exit -1
fiif [ $1 == "windows" ] && [ $2 == "debug" ]; thencmake \-G"Visual Studio 17 2022" -A x64 \-DCMAKE_BUILD_TYPE=Debug \-DCMAKE_CONFIGURATION_TYPES=Debug \-DSOCKPP_BUILD_SHARED=OFF \-DSOCKPP_BUILD_STATIC=ON \-DSOCKPP_BUILD_EXAMPLES=ON \-DCMAKE_INSTALL_PREFIX=install/debug \-Bbuild \.cmake --build build/ --target install --config debug
fiif [ $1 == "windows" ] && [ $2 == "release" ]; thencmake \-G"Visual Studio 17 2022" -A x64 \-DCMAKE_BUILD_TYPE=Release \-DCMAKE_CONFIGURATION_TYPES=Release \-DSOCKPP_BUILD_SHARED=OFF \-DSOCKPP_BUILD_STATIC=ON \-DSOCKPP_BUILD_EXAMPLES=ON \-DCMAKE_INSTALL_PREFIX=install/release \-Bbuild \.cmake --build build/ --target install --config release
fiif [ $1 == "linux" ] && [ $2 == "debug" ]; thencmake \-DCMAKE_BUILD_TYPE=Debug \-DSOCKPP_BUILD_SHARED=OFF \-DSOCKPP_BUILD_STATIC=ON \-DSOCKPP_BUILD_EXAMPLES=ON \-DCMAKE_INSTALL_PREFIX=install/debug \-Bbuild \.cmake --build build/ --target install --config debug
fiif [ $1 == "linux" ] && [ $2 == "release" ]; thencmake \-DCMAKE_BUILD_TYPE=Release \-DSOCKPP_BUILD_SHARED=OFF \-DSOCKPP_BUILD_STATIC=ON \-DSOCKPP_BUILD_EXAMPLES=ON \-DCMAKE_INSTALL_PREFIX=install/release \-Bbuild \.cmake --build build/ --target install --config release
firc=$?
if [[ ${rc} != 0 ]]; thenecho "Error: please check: ${rc}"exit ${rc}
fi

      以下为IPv4的测试代码:

      1.客户端测试代码如下:

int test_sockpp_client()
{sockpp::initialize();sockpp::tcp_connector conn({host, port});if (!conn) {std::cerr << "Error: connecting to server at: "<< sockpp::inet_address(host, port)<< ", message: " << conn.last_error_str() << std::endl;return -1;}std::cout << "created a connection from: " << conn.address() << std::endl;std::cout << "created a connection to " << conn.peer_address() << std::endl;// set a timeout for the responsesif (!conn.read_timeout(std::chrono::seconds(5))) {std::cerr << "Error: setting timeout on TCP stream: " << conn.last_error_str() << std::endl;}const std::vector<std::string> addr{"csdn", "github", "gitlab"};std::unique_ptr<unsigned char[]> buf(new unsigned char[len]);int index{0};std::atomic<bool> quit{ false };std::thread th([&quit] {std::this_thread::sleep_for(std::chrono::seconds(20));quit = true;});while (true) {if (quit) break;auto ret = conn.write(addr[index]);if (ret != addr[index].size()) {std::cerr << "Error: writing to the TCP stream: " << conn.last_error_str() << std::endl;break;}memset(buf.get(), 0, len);ret = conn.read(buf.get(), len);if (ret == -1) {std::cerr << "Error: reading from TCP stream: " << conn.last_error_str() << std::endl;break;}std::cout << addr[index] << ": " << buf.get() << std::endl;if (++index == addr.size()) index = 0;std::this_thread::sleep_for(std::chrono::seconds(1));}th.join();return 0;
}

      2.服务器端测试代码如下:

int test_sockpp_server()
{sockpp::initialize();sockpp::tcp_acceptor acc(port);if (!acc) {std::cerr << "Error: creating the acceptor: " << acc.last_error_str() << std::endl;return -1;}while (true) {sockpp::inet_address peer;// accept a new client connectionsockpp::tcp_socket sock = acc.accept(&peer);std::cout << "received a connection request from: " << peer << std::endl;if (!sock) {std::cerr << "Error: accepting incoming connection: " << acc.last_error_str() << std::endl;}else {// create a thread and transfer the new stream to itstd::thread th2(run_echo, std::move(sock));th2.detach();}}return 0;
}

      3.辅助code如下所示:

namespace {constexpr char* host{"127.0.0.1"};
constexpr in_port_t port{ 8888 };
constexpr int len {64};void run_echo(sockpp::tcp_socket sock)
{std::cout << "thread id: " << std::this_thread::get_id() << std::endl;std::map<std::string, std::string> addr;addr["csdn"] = "https://blog.csdn.net/fengbingchun";addr["github"] = "https://github.com/fengbingchun";std::unique_ptr<unsigned char[]> buf(new unsigned char[len]);while (true) {memset(buf.get(), 0, len);auto ret = sock.read(buf.get(), len);if (ret == -1) {std::cerr << "Error: reading from TCP stream: " << sock.last_error_str() << std::endl;break;}auto it = addr.find(std::string((char*)buf.get()));if (it != addr.end()) {sock.write(it->second);}elsesock.write("unkonwn");}
}} // namespace

      Windows上执行结果如下所示:模拟1个服务器端,3个客户端

      Linux上执行结果如下图所示:模拟1个服务器端,3个客户端

      GitHub:https://github.com/fengbingchun/OpenSSL_Test

相关文章:

C++套接字库sockpp介绍

sockpp是一个开源、简单、现代的C套接字库&#xff0c;地址为&#xff1a;https://github.com/fpagliughi/sockpp&#xff0c;最新发布版本为0.8.1&#xff0c;license为BSD-3-Clause。目前支持Linux、Windows、Mac上的IPv4、IPv6和Unix域套接字。其它*nix和POSIX系统只需很少的…...

Mac M2开发环境安装

持续更新 brew 安装 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"JAVA多版本环境 ## 终端下载安装 brew install --cask temurin8 brew install --cask temurin11 brew install --cask temurin17## vim ~/.…...

Linux各种版本安装详细步骤和root密码破解

文章目录 VMware新建虚拟机硬件设置设置虚拟网络挂载ISO文件 root密码破解 VMware新建虚拟机 硬件设置 设置虚拟网络 编辑>虚拟网络编辑器>VMnet8(NAT模式) 挂载ISO文件 加电>开启次虚拟机 第二项可以检查挂载上来的iso文件是否完整没有破坏 磁盘分区 选自定义分…...

Netty - 回顾Netty高性能原理和框架架构解析

文章目录 概述JDK 原生 NIO 程序的问题Why Netty使用场景Related ProjectsNetty 高性能设计I/O 模型【阻塞 I/O】&#xff1a;【I/O 复用模型】【基于 Buffer】 线程模型事件驱动模型Reactor 线程模型Netty的线程模型异步处理 Netty框架的架构设计功能特性模块组件Bootstrap、S…...

uni-app——項目day01

配置uni-app開發環境 uni-app快速上手 | uni-app官网 创建项目 图中四个划线就是要配置的地方. 选择vue2还是vue3看个人选择。 目录结构 但是现在新版本创建的项目已经没有components目录了&#xff0c;需要自己创建。 项目运行到微信开发者工具 使用git管理项目 node-mod…...

【Java、MongoDB】程序控制非关系数据库

步骤&#xff1a; &#xff08;1&#xff09;连接 连接字符串 &#xff08;2&#xff09;CRUD 类与接口 解析 &#xff08;3&#xff09;maven管理方法 依赖 <dependency><groupId>org.mongodb</groupId><artifactId>mongodb-driver-legacy<…...

MySQL查询时间处理相关函数与方法实践笔记

1. 实践案例 在查询mysql数据库获取数据时&#xff0c;有这样一个需求&#xff1a;按每30分钟分组获取电量数据&#xff0c;形成1天48个数据点。 方法一&#xff1a; select hour(a.CreateTime) 时点,case when MINUTE(a.CreateTime)<30 then 1 else 2 end 半小时,sum(a…...

springboot全局拦截sql异常

起因:非法用户可通过特定的输入(如输入内容超长)等操作,使后台逻辑发生错误,从而使后台sql语句暴露至前台,进而为sql攻击提供条件 处理流程:经查找com.mysql.cj.jdbc.exceptions的父类为SQLException,在全局异常处理类中增加如下配置,经测试不起作用 ExceptionHandler(SQLExce…...

AlGaN/GaN HFET 五参数模型

标题&#xff1a;A Five-Parameter Model of the AlGaN/GaN HFET 来源&#xff1a;IEEE TRANSACTIONS ON ELECTRON DEVICES&#xff08;15年&#xff09; 摘要—我们引入了AlGaN/GaN异质结场效应晶体管&#xff08;HFET&#xff09;漏极电流Id&#xff08;Vgs&#xff0c;Vds…...

矩阵的除法

B/A 如果矩阵A可逆&#xff0c;那么 证明&#xff1a; A/AB 如果矩阵A和B都可逆&#xff0c;那么 证明&#xff1a;...

Java中的 向上转型 | 向下转型

目录 一.向上转型 直接赋值 总结&#xff1a; 通过传参 通过返回值 二.向下转型 instanceof 一.向上转型 向上转型其实就是创建一个子类对象&#xff0c;并将其当作父类对象来使用&#xff0c;一般语法格式如下&#xff1a; 父类类型 对象名 new 子类类型() 一般有以…...

【华为OD机试AB高分必刷题目】朋友圈(C++-并查集Union-Find实现)

🚀你的旅程将在这里启航!本专栏所有题目均包含优质解题思路,高质量解题代码,详细代码讲解,助你深入学习,高分通过! 文章目录 【华为OD机试AB高分必刷题目】朋友圈(C++-并查集Union-Find实现)题目描述解题思路C++题解代码代码OJ评判结果代码讲解寄语【华为OD机试AB高分…...

前端面试题之vue篇

vue基础 vue的基本原理 当一个Vue实例创建时&#xff0c;Vue会遍历data中的属性&#xff0c;用Object.defineProperty(Vue使用proxy)转换为getter/setter&#xff0c;并且在内部追踪相关依赖&#xff0c;在属性被访问和修改时通知变化。每个组件实例都有相应的watcher程序实例…...

Java进阶(垃圾回收GC)——理论篇:JVM内存模型 垃圾回收定位清除算法 JVM中的垃圾回收器

前言 JVM作为Java进阶的知识&#xff0c;是需要Java程序员不断深度和理解的。 本篇博客介绍JVM的内存模型&#xff0c;对比了1.7和1.8的内存模型的变化&#xff1b;介绍了垃圾回收的语言发展&#xff1b;阐述了定位垃圾的方法&#xff0c;引用计数法和可达性分析发以及垃圾清…...

GaN HEMT 电容的分析建模,包括寄生元件

标题&#xff1a;Analytical Modeling of Capacitances for GaN HEMTs, Including Parasitic Components 来源&#xff1a;IEEE TRANSACTIONS ON ELECTRON DEVICES&#xff08;14年&#xff09; 摘要&#xff1a;本文提出了一种基于表面势的终端电荷和电容模型&#xff0c;包…...

Python实战 | 使用 Python 和 TensorFlow 构建卷积神经网络(CNN)进行人脸识别

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…...

JLink edu mini 10Pin接口定义

注意&#xff1a;SWD接口在阵脚2&#xff0c;4&#xff1b;而20Pin的SWD接口在阵脚7&#xff0c;9 参考&#xff1a;1 官网资料&#xff1b; 2 【润石RS0104YQ Demo开发板测试分享】J-Link EDU Mini调试5V系统_国产运算放大器_模拟开关_线性稳压器_电平转换器_小逻辑_比较器…...

compile: version “go1.19“ does not match go tool version “go1.18.1“

** 1 安装了新版本的go后 为什么go version 还是旧版本&#xff1f; ** 如果你已经按照上述步骤安装了新版本的 Go&#xff0c;但 go version 命令仍然显示旧版本&#xff0c;可能是因为你的环境变量设置不正确或未正确生效。你可以尝试以下方法来解决问题&#xff1a; 重新…...

spring boot security 自定义AuthenticationProvider

spring boot security 自定义AuthenticationProvider 基于 spring boot 3.x 场景实现 手机验证码登陆 实现 CaptureCodeAuthenticationFilter public class CaptureCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {private static final Strin…...

某电力设计公司绩效考核优化项目成功案例纪实

——引入角色定位考核法&#xff0c;建立多维度评价体系&#xff0c;支持业务转型后的客观评价 【客户行业】电力行业 【问题类型】绩效考核 【客户背景及现状分析】 某电力设计公司成立于2000年左右&#xff0c;是一家从事输变电工程勘察、设计、咨询的专业公司&#xff0c…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...

从实验室到产业:IndexTTS 在六大核心场景的落地实践

一、内容创作&#xff1a;重构数字内容生产范式 在短视频创作领域&#xff0c;IndexTTS 的语音克隆技术彻底改变了配音流程。B 站 UP 主通过 5 秒参考音频即可克隆出郭老师音色&#xff0c;生成的 “各位吴彦祖们大家好” 语音相似度达 97%&#xff0c;单条视频播放量突破百万…...