C++套接字库sockpp介绍

news2025/4/6 23:03:11

      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/bash

if [ $# != 2 ]; then
    echo "Error: requires two parameters: 1: windows or linux; 2: release or debug"
    echo "For example: $0 windows debug"
    exit -1
fi

if [ $1 != "windows"  ] && [ $1 != "linux" ]; then
    echo "Error: the first parameter can only be windows or linux"
    exit -1
fi

if [ $2 != "debug" ] && [ $2 != "release" ]; then
    echo "Error: the second parameter can only be debug or release"
    exit -1
fi

if [ $1 == "windows" ] && [ $2 == "debug" ]; then
    cmake \
        -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
fi

if [ $1 == "windows" ] && [ $2 == "release" ]; then
    cmake \
        -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
fi

if [ $1 == "linux" ] && [ $2 == "debug" ]; then
    cmake \
        -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
fi

if [ $1 == "linux" ] && [ $2 == "release" ]; then
    cmake \
        -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
fi

rc=$?
if [[ ${rc} != 0 ]]; then
    echo "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 responses
    if (!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 connection
		sockpp::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 it
			std::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);
		}
		else
			sock.write("unkonwn");
	}
}

} // namespace

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

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

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

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

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

相关文章

冯·诺伊曼体系结构--操作系统

文章目录 1.认识冯诺依曼系统1.1约翰冯诺依曼1.2冯诺依曼结构1.3存储器的读写速度1.4对冯诺依曼结构的认识1.5冯诺依曼结构在生活中的演示 2.操作系统--“搞管理”的软件2.1概念2.2OS存在的意义2.3管理的方式2.4系统调用和库函数概念 1.认识冯诺依曼系统 1.1约翰冯诺依曼 1.2冯…

【论文】利用移动性的比例公平蜂窝调度测量和算法

&#xff08;一支笔一包烟&#xff0c;一节论文看一天 &#xff09;&#xff08;一张纸一瓶酒&#xff0c;一道公式推一宿&#xff09; 摘要1. 引言2. 相关工作3. 模型和问题公式4. 预测FPF调度 &#xff08; P F &#xff09; 2 S &#xff08;PF&#xff09;^2S &#xff08;…

js 加密解密 cryptojs(对称加密库)

js 加密解密可以使用 crypto-js 这是一个对称加密的库&#xff0c; 可以使用 AES DES 但没有 rsa 等非对称加密的方法 安装方法 npm install crypto-js 它可以进行 MD5 SHA-1 SHA-256 Base64 AES DES 等算法和加密 import crypto from "crypto-js"let md5binary cry…

通过防火墙禁止访问指定网站(个人电脑,Windows系统)

背景 近年沉迷B站视频不能自拔&#xff0c;使用了诸多手段禁用&#xff0c;都很容易破戒。为了彻底杜绝B站的使用&#xff0c;决定手动进行设置。在ChatGPT和文心一言提问&#xff0c;得到了以下四种方法&#xff08;按个人认为的戒断水平由低到高排序&#xff09;&#xff1a;…

AI驱动的软件测试,何时可以信赖?

综合编译&#xff5c;TesterHome社区 作者&#xff5c;Yuliya Vasilko&#xff0c;数据工程师 以下为作者观点&#xff1a; 越来越多的组织转向人工智能&#xff08;AI&#xff09;驱动的测试解决方案&#xff0c;以简化质量保证流程并提高软件可靠性。 随着对人工智能的依赖程…

HDRP图形入门:HDRP渲染管线depth翻转

新项目开坑HDRP渲染管线&#xff0c;花了些时间把项目开发框架和图形工作流更新到最新版本&#xff0c;其间发现HDRP中深度信息和buildin渲染管线翻转了。 以前的buildin渲染管线&#xff0c;距离摄像机越近depth->0&#xff0c;越远depth->1&#xff0c;这也很好理…

JAVA毕业设计110—基于Java+Springboot+Vue的房屋租赁系统小程序(源码+数据库)

基于JavaSpringbootVue的房屋租赁系统小程序(源码数据库)110 一、系统介绍 本系统前后端分离 本系统分为用户、房东、超级管理员三种角色 1、用户&#xff1a; 登录、注册、房屋搜索、房屋收藏、看房预约、租房申请、租房记录、看房记录、收藏记录、我的消息、个人信息修改…

js动态显示当前时间

目录 1、封装时间函数 2、在页面写一个div标签&#xff0c;用来存放时间 3、获取div标签&#xff0c;开启定时器&#xff0c;时间为1000ms 4、先调用时间函数&#xff0c;防止页面加载延迟&#xff0c;再在定时器里调用 完整代码 效果图 1、封装时间函数 function getTi…

美团2024届秋招笔试第二场编程真题-小美的数组构造

分析&#xff1a;暴力角度看&#xff0c;因为数组a和b总和一样&#xff0c;所以实际上是将总和m划分为n个数字&#xff0c;且每个数字都和a数组不一样的方案数。当然会超时。从数据角度看&#xff0c;平方级别算法是可以的。 其实用动态规划的四步法分析起来还是很简单的&…

游戏平台采集数据

首先&#xff0c;你需要在你的项目中添加Kotlin的网络库&#xff0c;例如OkHttp。你可以在你的build.gradle文件中添加以下依赖&#xff1a; dependencies {implementation com.squareup.okhttp3:okhttp:4.9.0 }然后&#xff0c;你可以使用以下代码来创建一个基本的网络爬虫&a…

数据库安全:MySQL 身份认证漏洞(CVE-2012-2122)

数据库安全&#xff1a;MySQL 身份认证漏洞&#xff08;CVE-2012-2122&#xff09; MySQL 身份认证漏洞是一个身份认证绕过漏洞&#xff0c;该漏洞的核心原理涉及到 MySQL 在处理身份认证时的一个安全缺陷&#xff0c;这个漏洞可以使攻击者可以绕过安全身份认证&#xff0c;从…

【大模型】大语言模型语料下载

文章目录 概述Hugging Faceobs操作git-lfs例子RedPajama-Data-1TSlimPajama-627B/git clone续传 数据格式参考资料 概述 大模型训练中语料是非常重要的&#xff0c;目前公网上有各种各样的语料可以供下载&#xff0c;但是不可能每个用户、每次训练任务都通过公网去拉取语料&am…

CV计算机视觉每日开源代码Paper with code速览-2023.11.9

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【3D目标检测】3DiffTection: 3D Object Detection with …

代码随想录算法训练营|第五十天

买卖股票的最佳时机含冷冻期 309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; public class Solution {public int MaxProfit(int[] prices) {if(prices.Length 0)return 0;int[,] dp new int[prices.Length1,4];dp[0,0] -prices[0];for(int i1;i&…

NSF服务器

1.简介 1.1 NFS背景介绍 NFS是一种古老的用于在UNIX/Linux主机之间进行文件共享的协议。它古老到你必须穿着白大补才能接近一台计算机的年代。在那个年代&#xff0c;所有的联网计算机都被认为是可信的&#xff0c;而不像现今这样&#xff0c;任何人都有多种多样方法能连接到你…

免费3D骨架工具

免费3D骨架工具 : https://posemy.art/ ControlNet 1.1http://www.coloradmin.cn/o/839105.html?actiononClick https://pan.baidu.com/s/1rh39DI9xVbguLO5l7O4pjA yqqe  网盘里的 预处理器/downloads文件夹&#xff08;包含所有预处理器&#xff09;直接放在 extensions/sd…

功能案例 -- 拖拽上传文件,生成缩略图

直接看效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>拖拽上传文件</title>&l…

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系统_国产运算放大器_模拟开关_线性稳压器_电平转换器_小逻辑_比较器…

图解算法数据结构-LeetBook-数组03_除本身之外乘积

为了深入了解这些生物群体的生态特征&#xff0c;你们进行了大量的实地观察和数据采集。数组 arrayA 记录了各个生物群体数量数据&#xff0c;其中 arrayA[i] 表示第 i 个生物群体的数量。请返回一个数组 arrayB&#xff0c;该数组为基于数组 arrayA 中的数据计算得出的结果&am…

联系作者方式的教程

首先你应该目前是在付费资源运行效果的展示文章页面&#xff0c;如下所示 然后一直往下滑&#xff0c;滑到这个文章的最下面&#xff0c;就可以看到我的推广名片&#xff0c;最后点击这个名片就可以获取到我的联系方式了~