1. boost::asio之socket的创建和连接

网络编程基本流程

网络编程的基本流程对于服务端是这样的
服务端
1)socket——创建socket对象。

2)bind——绑定本机ip+port。

3)listen——监听来电,若在监听到来电,则建立起连接。

4)accept——再创建一个socket对象给其收发消息。原因是现实中服务端都是面对多个客户端,那么为了区分各个客户端,则每个客户端都需再分配一个socket对象进行收发消息。

5)read、write——就是收发消息了。

对于客户端是这样的
客户端
1)socket——创建socket对象。

2)connect——根据服务端ip+port,发起连接请求。

3)write、read——建立连接后,就可发收消息了。

图示如下
在这里插入图片描述

终端节点的创建

所谓终端节点就是用来通信的端对端的节点,可以通过ip地址和端口构造,其的节点可以连接这个终端节点做通信.
如果我们是客户端,我们可以通过对端的ip和端口构造一个endpoint,用这个endpoint和其通信。

类"boost:asio:ip:address"没有成员"from_string”

在这里插入图片描述


int  client_end_point() {// Step 1. Assume that the client application has already // obtained the IP-address and the protocol port number.std::string raw_ip_address = "127.0.0.1";unsigned short port_num = 3333;// Used to store information about error that happens// while parsing the raw IP-address.boost::system::error_code ec;// Step 2. Using IP protocol version independent address// representation.asio::ip::address ip_address =asio::ip::address::from_string(raw_ip_address, ec);if (ec.value() != 0) {// Provided IP address is invalid. Breaking execution.std::cout<< "Failed to parse the IP address. Error code = "<< ec.value() << ". Message: " << ec.message();return ec.value();}// Step 3.asio::ip::tcp::endpoint ep(ip_address, port_num);// Step 4. The endpoint is ready and can be used to specify a // particular server in the network the client wants to // communicate with.return 0;
}

如果是服务端,则只需根据本地地址绑定就可以生成endpoint


nt  server_end_point(){// Step 1. Here we assume that the server application has//already obtained the protocol port number.unsigned short port_num = 3333;// Step 2. Create special object of asio::ip::address class// that specifies all IP-addresses available on the host. Note// that here we assume that server works over IPv6 protocol.asio::ip::address ip_address = asio::ip::address_v6::any();// Step 3.asio::ip::tcp::endpoint ep(ip_address, port_num);// Step 4. The endpoint is created and can be used to // specify the IP addresses and a port number on which // the server application wants to listen for incoming // connections.return 0;
}

创建socket

创建socket分为4步,创建上下文iocontext,选择协议,生成socket,打开socket。


int create_tcp_socket() {// Step 1. An instance of 'io_service' class is required by// socket constructor. asio::io_context  ios;// Step 2. Creating an object of 'tcp' class representing// a TCP protocol with IPv4 as underlying protocol.asio::ip::tcp protocol = asio::ip::tcp::v4();// Step 3. Instantiating an active TCP socket object.asio::ip::tcp::socket sock(ios);// Used to store information about error that happens// while opening the socket.boost::system::error_code ec;// Step 4. Opening the socket.sock.open(protocol, ec);if (ec.value() != 0) {// Failed to open the socket.std::cout<< "Failed to open the socket! Error code = "<< ec.value() << ". Message: " << ec.message();return ec.value();}return 0;
}

上述socket只是通信的socket,如果是服务端,我们还需要生成一个acceptor的socket,用来接收新的连接。


int  create_acceptor_socket() {// Step 1. An instance of 'io_service' class is required by// socket constructor. asio::io_context ios;// Step 2. Creating an object of 'tcp' class representing// a TCP protocol with IPv6 as underlying protocol.asio::ip::tcp protocol = asio::ip::tcp::v6();// Step 3. Instantiating an acceptor socket object.asio::ip::tcp::acceptor acceptor(ios);// Used to store information about error that happens// while opening the acceptor socket.boost::system::error_code ec;// Step 4. Opening the acceptor socket.acceptor.open(protocol, ec);if (ec.value() != 0) {// Failed to open the socket.std::cout<< "Failed to open the acceptor socket!"<< "Error code = "<< ec.value() << ". Message: " << ec.message();return ec.value();}return 0;
}

绑定acceptor

对于acceptor类型的socket,服务器要将其绑定到指定的断点,所有连接这个端点的连接都可以被接收到。


int  bind_acceptor_socket() {// Step 1. Here we assume that the server application has// already obtained the protocol port number.unsigned short port_num = 3333;// Step 2. Creating an endpoint.asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(),port_num);// Used by 'acceptor' class constructor.asio::io_context  ios;// Step 3. Creating and opening an acceptor socket.asio::ip::tcp::acceptor acceptor(ios, ep.protocol());boost::system::error_code ec;// Step 4. Binding the acceptor socket.acceptor.bind(ep, ec);// Handling errors if any.if (ec.value() != 0) {// Failed to bind the acceptor socket. Breaking// execution.std::cout << "Failed to bind the acceptor socket."<< "Error code = " << ec.value() << ". Message: "<< ec.message();return ec.value();}return 0;
}

连接指定的端点

作为客户端可以连接服务器指定的端点进行连接


int  connect_to_end() {// Step 1. Assume that the client application has already// obtained the IP address and protocol port number of the// target server.std::string raw_ip_address = "127.0.0.1";unsigned short port_num = 3333;try {// Step 2. Creating an endpoint designating // a target server application.asio::ip::tcp::endpointep(asio::ip::address::from_string(raw_ip_address),port_num);asio::io_context ios;// Step 3. Creating and opening a socket.asio::ip::tcp::socket sock(ios, ep.protocol());// Step 4. Connecting a socket.sock.connect(ep);// At this point socket 'sock' is connected to // the server application and can be used// to send data to or receive data from it.}// Overloads of asio::ip::address::from_string() and // asio::ip::tcp::socket::connect() used here throw// exceptions in case of error condition.catch (system::system_error& e) {std::cout << "Error occured! Error code = " << e.code()<< ". Message: " << e.what();return e.code().value();}
}

域名


int dns_connect_to_end() {std::string host = "llfc.club";//域名std::string port_num = "3333";asio::io_context ioc;boost::asio::ip::tcp::resolver resolver(ioc);//asio::ip::tcp::resolver::query resolver_query(host,port_num,asio::ip::tcp::resolver::query::numeric_service);//DNS解析器try{auto endpoints = resolver.resolve(host, port_num);//创建socket并连接到对应的地址asio::ip::tcp::socket sock(ioc);asio::connect(sock, endpoints);}catch (system::system_error& e){std::cout << "Error occured! Error code = " << e.code()<< ". Message: " << e.what();return e.code().value();}
}

服务器接收连接

当有客户端连接时,服务器需要接收连接


int accept_new_connection(){// The size of the queue containing the pending connection// requests.const int BACKLOG_SIZE = 30;// Step 1. Here we assume that the server application has// already obtained the protocol port number.unsigned short port_num = 3333;// Step 2. Creating a server endpoint.asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(),port_num);asio::io_context  ios;try {// Step 3. Instantiating and opening an acceptor socket.asio::ip::tcp::acceptor acceptor(ios, ep.protocol());// Step 4. Binding the acceptor socket to the // server endpint.acceptor.bind(ep);// Step 5. Starting to listen for incoming connection// requests.acceptor.listen(BACKLOG_SIZE);// Step 6. Creating an active socket.asio::ip::tcp::socket sock(ios);// Step 7. Processing the next connection request and // connecting the active socket to the client.acceptor.accept(sock);// At this point 'sock' socket is connected to //the client application and can be used to send data to// or receive data from it.}catch (system::system_error& e) {std::cout << "Error occured! Error code = " << e.code()<< ". Message: " << e.what();return e.code().value();}
}

关于buffer

任何网络库都有提供buffer的数据结构,所谓buffer就是接收和发送数据时缓存数据的结构。
boost::asio提供了asio::mutable_buffer 和 asio::const_buffer这两个结构,他们是一段连续的空间,首字节存储了后续数据的长度。
asio::mutable_buffer用于写服务,asio::const_buffer用于读服务。但是这两个结构都没有被asio的api直接使用。
对于api的buffer参数,asio提出了MutableBufferSequence和ConstBufferSequence概念,他们是由多个asio::mutable_buffer和asio::const_buffer组成的。也就是说boost::asio为了节省空间,将一部分连续的空间组合起来,作为参数交给api使用。
我们可以理解为MutableBufferSequence的数据结构为std::vectorasio::mutable_buffer
结构如下

在这里插入图片描述
每隔vector存储的都是mutable_buffer的地址,每个mutable_buffer的第一个字节表示数据的长度,后面跟着数据内容。
这么复杂的结构交给用户使用并不合适,所以asio提出了buffer()函数,该函数接收多种形式的字节流,该函数返回asio::mutable_buffers_1 o或者asio::const_buffers_1结构的对象。
如果传递给buffer()的参数是一个只读类型,则函数返回asio::const_buffers_1 类型对象。
如果传递给buffer()的参数是一个可写类型,则返回asio::mutable_buffers_1 类型对象。
asio::const_buffers_1和asio::mutable_buffers_1是asio::mutable_buffer和asio::const_buffer的适配器,提供了符合MutableBufferSequence和ConstBufferSequence概念的接口,所以他们可以作为boost::asio的api函数的参数使用。
简单概括一下,我们可以用buffer()函数生成我们要用的缓存存储数据。
比如boost的发送接口send要求的参数为ConstBufferSequence类型

在这里插入图片描述
在这里插入图片描述


void use_stream_buffer() {asio::streambuf buf;std::ostream output(&buf);// Writing the message to the stream-based buffer.output << "Message1\nMessage2";// Now we want to read all data from a streambuf// until '\n' delimiter.// Instantiate an input stream which uses our // stream buffer.std::istream input(&buf);// We'll read data into this string.std::string message1;std::getline(input, message1);// Now message1 string contains 'Message1'.
}

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

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

相关文章

WPF 控制动画开关

记录一种实现方式&#xff1a;第一步&#xff1a;首先定义一个静态类&#xff0c;提供依赖属性&#xff0c;进而方便在xaml中实现绑定&#xff1a;public static class AnimationBehavior{// 定义附加属性public static readonly DependencyProperty IsAnimatingProperty Depen…

元素竖向的百分比设定是相对于父容器的高度吗?

元素竖向的百分比设定是相对于父容器的高度吗&#xff1f; 核心问题 在CSS中&#xff0c;当设置元素的竖向属性&#xff08;如height、padding-top等&#xff09;为百分比值时&#xff0c;其计算基准是父容器的高度还是宽度&#xff1f; 权威结论height属性 百分比值基于父容器…

web3.0怎么入局

Web3.0(第三代互联网)融合了区块链、去中心化应用(DApps)、NFT、DAO等新兴技术,给个人和机构提供了许多全新的赚钱机会。入局 Web3.0 赚钱主要有以下几种途径,根据你的技术背景、资金能力和时间投入可以选择适合自己的方式。 目录 一、普通用户赚钱方式(门槛低) 1. …

linux入门 相关linux系统操作命令(二)--文件管理系统 ubuntu22.04

以下有免费的4090云主机提供ubuntu22.04系统的其他入门实践操作 地址&#xff1a;星宇科技 | GPU服务器 高性能云主机 云服务器-登录 相关兑换码星宇社区---4090算力卡免费体验、共享开发社区-CSDN博客 兑换码要是过期了&#xff0c;可以私信我获取最新兑换码&#xff01;&a…

Python-初学openCV——图像预处理(二)

目录 一、图像仿射变换 1、基本性质 二、cv2.warpAffine() 函数 1、图像旋转 2、图像平移 3、图像缩放 4、图像剪切 三、 插值方法 1、最近邻插值 2、双线性插值 3、像素区域插值 4、双三次插值 5、Lanczos插值 一、图像仿射变换 仿射变换&#xff08;Affine Tr…

医疗AI轻量化部署方案的深度梳理与优化路径判研

摘要 医疗AI的快速发展为精准诊断、个性化治疗和医疗资源优化提供了新机遇。然而,大规模模型的高计算复杂度和资源需求限制了其在资源受限环境(如边缘设备、基层医疗机构)的应用。本文系统梳理了医疗AI轻量化部署的核心技术体系,包括模型压缩、参数高效微调(PEFT)、边缘-…

SSP通过SDK对接流量的原理与实现

一、核心概念解析 1.1 SSP&#xff08;供应方平台&#xff09; 定义&#xff1a;SSP是程序化广告生态中媒体方的核心工具&#xff0c;通过自动化技术帮助媒体&#xff08;如网站、应用、视频平台&#xff09;管理广告资源、优化填充率并最大化广告收益。核心功能&#xff1a;…

如何清理电脑c盘内存 详细操作步骤

电脑使用时间不断延长&#xff0c;许多用户可能会遇到一个问题——C盘空间不足&#xff0c;导致系统运行缓慢或无法安装新程序。如果C盘的存储空间被大量占用&#xff0c;可能会影响到计算机的性能。本文将介绍几种有效的方法&#xff0c;帮助你清理C盘内存&#xff0c;释放空间…

ESP32的ADF详解:5. Streams的API

一、算法流 (algorithm stream) 1. 初始化与配置API功能描述关键参数说明algo_stream_init()初始化算法流&#xff08;AEC/AGC/NS/VAD&#xff09;config->algo_mask 选择算法组合config->sample_rate 设置采样率&#xff08;默认16kHz&#xff09;config->partition_…

JavaScript对象键序问题解析

问题的发现&#xff1a; 我有一个接口返回一个json数据浏览器network里的Response里是从大到小排。 但Preview就是反过来的 问题的描述&#xff1a; 上面那个让我发现浏览器处理对象或者json是会对其键值对做排序&#xff01;&#xff01;&#xff01; 在JavaScript中&am…

pandas库的数据导入导出,缺失值,重复值处理和数据筛选,matplotlib库 简单图绘制

目录 一.数据导入导出 1.CSV文件读取与参数说明 2.Excel与TST文件读取 3.数据导出操作 二.缺失值处理 1.填充缺失值 2.删除缺失值【删除整行数据】 三.重复值处理 四.数据筛选与条件查询 1.逻辑判断取数 2.字符匹配 3.逻辑运算&#xff1a; &&#xff08;和&…

FPGA 如何实现另一个 FPGA?

如果你对 FPGA 有些了解&#xff0c;大概知道它的意思是“可编程逻辑器件”&#xff0c;可以把写好的逻辑电路&#xff08;通常是 Verilog/VHDL&#xff09;通过工具综合、布局布线、烧写进去&#xff0c;让一块芯片变成“你想要的电路”。但如果我告诉你&#xff0c;现在有个开…

文思助手、新华妙笔 AI材料星的公文写作深度测评

公文写作一直都是体制内工作人员的日常核心任务&#xff0c;写公文的难点不仅来自于对政策表述严谨性的高要求&#xff0c;也在于格式规范、内容深度以及效率压力的多重考验。随着AI技术的发展&#xff0c;越来越多的文字辅助工具出现&#xff0c;很大程度的缓解了写作压力&…

Flutter开发环境搭建与工具链

Flutter开发实战第1章&#xff1a;Flutter开发环境搭建与工具链1.1 Flutter简介与优势Flutter是Google推出的开源UI工具包&#xff0c;用于从单一代码库构建编译为原生性能的移动、Web和桌面应用程序。Flutter的核心优势包括&#xff1a;跨平台一致性&#xff1a;一套代码运行在…

io_uring:Linux异步I/O的革命性突破

目录 1. io_uring是什么&#xff1f; io_uring核心优势&#xff1a; 2. io_uring核心原理 2.1 双环形缓冲区设计 2.2 关键数据结构 1、完成队列CQ 2、提交队列SQ 3、Params 3. io_uring工作流程 3.1 初始化阶段 3.2 I/O操作流程 4. C代码示例&#xff08;原始系统调…

线段树学习笔记 - 练习题(2)

文章目录1. 前言2. P3870 [TJOI2009] 开关3. P2184 贪婪大陆4. P1438 无聊的数列5. P1471 方差1. 前言 线段树系列文章&#xff1a; 线段树学习笔记。线段树学习笔记 - 练习题&#xff08;1&#xff09;。 前一篇做了几道线段树的题目&#xff0c;这篇文章就继续看下线段树的…

Vue状态管理:Pinia 与 Vuex 的使用方法与对比【文章附有完整案例】

最近在接手vue项目的需求&#xff0c;因为之前一直在做react的需求&#xff0c;日常的vue练习也少了很多&#xff0c;导致现在接手vue项目&#xff0c;很多关于vue的知识点基本上忘得干干净净了。但是好在有基础&#xff0c;重新学也会很快掌握。分享这个过程中的一些复习内容。…

OpenMed 项目深度分析:推动医疗 NLP 领域的开源革命

摘要 医疗人工智能(AI)领域因高质量数据和模型的获取受限而发展缓慢。OpenMed 项目通过开源超过380个医疗命名实体识别(NER)模型,显著降低了研究与应用门槛。本文从项目背景、技术优势、应用场景、实施挑战及未来展望五个方面,系统分析 OpenMed 的核心价值与潜力,揭示其…

大模型开发

什么是Ai&#xff1f;AI的全拼是(Artificial Intelligence)人工智能&#xff0c;使机器能够像人类一样思考、学习和解决问题的技术。在AI的应用情况下我们更多的是学习自然语言处理。在自然语言处理(Natural Language Processing&#xff0c;NLP)中&#xff0c;有一项关键技术叫…

【正常配置了beast扩展,phpinfo信息也显示了,但是就是不运行】

正常配置了beast扩展&#xff0c;phpinfo信息也显示了&#xff0c;但是就是不运行场景原因解决排查过程扩展场景 项目中使用到了beast进行源码保护&#xff0c;指定类存在&#xff0c;但是报错信息提示类找不到&#xff0c;beast扩展添加到了正在运行的php版本下的ext文件夹下…