【Asio网络编程】socket的监听和连接

news2024/9/23 19:25:42

文章目录

  • 一、VS2019配置boost库
  • 二、 网络编程基本流程
  • 三、 终端节点的创建
    • 3.1 客户端终端节点
    • 3.2 服务端终端节点
  • 四、 创建SOCKET
    • 4.1 客户端创建socket
    • 4.2 服务端创建socket
    • 4.3 绑定acceptor
  • 五、 连接
    • 5.1 客户端连接
    • 5.2 客户端通过域名连接(了解即可,用的少)
    • 5.2 服务器接收连接


以下是本篇文章正文内容

一、VS2019配置boost库

打开visualstudio 创建一个控制台工程,然后右键工程选择属性
选择VC++目录—-》包含目录,添加boost的include文件;
选择VC++目录—-》库目录,添加 boost的lib文件;
并且把VS的Debug模式设置为x64
在这里插入图片描述

附上已经编译好的boost库链接:待补充

二、 网络编程基本流程

网络编程的基本流程对于服务端是这样的

  • 服务端
    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地址和端口构造,其的节点可以连接这个终端节点做通信.

3.1 客户端终端节点

通过对端的ip和端口构造一个endpoint,用这个endpoint和其通信。

int client_end_point()
{
    // Step 1. 假设客户端已经获取对端的IP和端口号
    std::string raw_ip_address = "127.0.0.1";  // 对端IP
    unsigned short port_num = 3333;  // 对端端口号

     // Step 2. 使用IP字符串转换为address类型
    boost::system::error_code ec;  // 错误码,出现错误时非0
    // 将字符串形式的 IP 地址转换为 asio::ip::address 类型的对象
    asio::ip::address ip_address = asio::ip::address::from_string(raw_ip_address, ec);

    // 如果出错
    if (ec.value()!=0) {
        std::cout << "Failed to parse the IP. Error code=" << ec.value();
        return ec.value();
    }

    // Step 3.使用 IP 地址和端口号创建 endpoint 对象,endpoint 对象用于表示套接字的本地或远程端点
    /*
    endpoint 对象的一些主要用途:
    1. 套接字绑定:服务器端的套接字可以使用 endpoint 对象来绑定到一个特定的 IP 地址和端口,从而监听来自客户端的连接请求。
    2. 连接建立:客户端的套接字可以使用 endpoint 对象来指定它想要连接到的服务器的 IP 地址和端口。
    3. 获取远程端点信息:对于已经建立的连接,可以通过套接字获取连接的远程端点信息,这通常用于日志记录、监控或安全检查。
    */
    asio::ip::tcp::endpoint ep(ip_address, port_num);

    /*
     Step 4. 端点已准备好,可用于指定客户端想要与其通信的网络中的特定服务器。
    */

	return 0;
}

3.2 服务端终端节点

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

int  server_end_point() {
    // Step 1. 假设服务器应用程序已经获得了协议端口号。
    unsigned short port_num = 3333;

    // Step 2. 创建asio::ip::地址类的特殊对象,该类指定主机上所有可用的ip地址。
    // asio::ip::address_v6::any() 用于创建一个表示 IPv6 地址的 asio::ip::address 对象,它代表 IPv6 的任意地址。
    // 这个地址通常在服务器端用于绑定套接字,以便监听所有 IPv6 地址上的指定端口。
    asio::ip::address ip_address = asio::ip::address_v6::any();

    // Step 3.创建endpoint
    asio::ip::tcp::endpoint ep(ip_address, port_num);

    // Step 4. 已被创建的endpoint可用于 指定服务器应用程序 要侦听传入连接的IP地址和端口号。

    return 0;
}

四、 创建SOCKET

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

4.1 客户端创建socket

int create_tcp_socket()
{
    // Step 1. 创建上下文
    asio::io_context  ios;

    // Step 2. 选择协议
    asio::ip::tcp protocol = asio::ip::tcp::v4();

    // Step 3. 生成SOCKET
    asio::ip::tcp::socket sock(ios);
    // 使用ec判断是否打开成功
    boost::system::error_code ec;

    // Step 4. 打开socket
    sock.open(protocol, ec);

    if (ec.value() != 0) {
        std::cout << "Failed to parse the IP. Error code=" << ec.value();
        return ec.value();
    }

    return 0;
}

4.2 服务端创建socket

服务端,还需要生成一个acceptor的socket,用来接收新的连接。

int  create_acceptor_socket() {
    // Step 1. 创建上下文
    asio::io_context ios;

    // Step 2. 创建一个“TCP”类的对象,表示以IPv6为底层协议的TCP协议。
    asio::ip::tcp protocol = asio::ip::tcp::v6();

    // Step 3. 实例化一个acceptor对象.
    asio::ip::tcp::acceptor acceptor(ios);

    // 错误码
    boost::system::error_code ec;

    // Step 4. 打开 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;
}

4.3 绑定acceptor

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

在这里插入代码片

五、 连接

5.1 客户端连接

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

int connect_to_end()
{
    // Step 1. IP地址和端口号
    std::string raw_ip_address = "127.0.0.1";
    unsigned short port_num = 3333;
    
    try {
        // Step 2. 创建endpoint
        asio::ip::tcp::endpoint ep(asio::ip::address::from_string(raw_ip_address), port_num);
        asio::io_context ios;
        
        // Step 3.创建并打开socket默认用的是v4协议
        asio::ip::tcp::socket sock(ios, ep.protocol());
       
        // Step 4. 连接socket.
        sock.connect(ep);
        // 此时,套接字“sock”已连接到服务器应用程序,可以用于发送数据或从它接收数据。
    }
    // 错误抛出异常
    catch (system::system_error& e) {
        std::cout << "Error occured! Error code = " << e.code()
            << ". Message: " << e.what();
        return e.code().value();
    }
    return 0;
}

5.2 客户端通过域名连接(了解即可,用的少)

int dns_connect_to_end()
{
    // Step 1. 域名和端口号
    std::string host = "www.baidu.club";
    std::string port_num = "333";

    asio::io_context ios;
    // 查询器,第三个参数是库提供的,不用过多了解
    asio::ip::tcp::resolver::query resolver_query(host, port_num, asio::ip::tcp::resolver::query::numeric_service);
    // 域名解析器
    asio::ip::tcp::resolver resolver(ios);
     
    try {
        // 将解析到的域名所对应的所有IP返回为迭代器中(一个域名可以有多个IP)
        asio::ip::tcp::resolver::iterator it = resolver.resolve(resolver_query);

        // 创建socket
        asio::ip::tcp::socket sock(ios);
        // 连接socket
        asio::connect(sock, it);

        // 此时,套接字“sock”已连接到服务器应用程序,可以用于发送数据或从它接收数据。
    }
    // 错误抛出异常
    catch (system::system_error& e) {
        std::cout << "Error occured! Error code = " << e.code()
            << ". Message: " << e.what();
        return e.code().value();
    }
    return 0;
}

5.2 服务器接收连接

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

int accept_new_connection()
{
    //  监听队列的大小,队列中缓存来不及处理的连接
    const int BACKLOG_SIZE = 30;
    
    // Step 1. 端口号
    unsigned short port_num = 3333;
    // Step 2.创建endpoint.
    asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(), port_num);
    asio::io_context  ios;
    try {
        // Step 3. 创建并打开acceptor socket.
        asio::ip::tcp::acceptor acceptor(ios, ep.protocol());
        
        // Step 4. 绑定acceptor socket到endpint.
        acceptor.bind(ep);
       
        // Step 5. 开始监听即将到来的连接请求
        acceptor.listen(BACKLOG_SIZE);
        
        // Step 6. 服务器创建一个活跃的 socket,用以和客户端通信,
        // acceptor接收连接交给socket处理
        asio::ip::tcp::socket sock(ios);
        acceptor.accept(sock);
        
        // 此时,“sock”套接字连接到客户端应用程序,可以用于发送数据或从它接收数据。
    }
    catch (system::system_error& e) {
        std::cout << "Error occured! Error code = " << e.code()
            << ". Message: " << e.what();
        return e.code().value();
    }
    return 0;
}

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

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

相关文章

使用 curl_cffi 解决 Web 抓取中的 TLS/JA3 指纹识别方法

在网站抓取过程中遇到反爬虫措施而苦苦挣扎&#xff1f;curl_cffi 是一个高级 Python 库&#xff0c;它包装了 cURL 工具&#xff0c;可以帮助您有效地绕过这些障碍。通过模拟浏览器行为并利用 cURL 的功能&#xff0c;curl_cffi 增强了您的抓取器避免检测并顺利执行的能力。在…

索迪迈科技油罐车监控系统中车载摄像头的布局策略

随着科技的不断发展&#xff0c;车载监控系统在油罐车上的安装已经成为了一种趋势。这不仅大大降低了车辆的安全隐患与运营成本&#xff0c;更对石油运输企业优化资源配置、提高市场竞争力起到了积极的促进作用。那么&#xff0c;在油罐车监控系统中&#xff0c;如何合理布局车…

Baumer工业相机堡盟工业相机如何通过NEOAPISDK实现根据每次触发信号移动感兴趣区域ROI(Python)

Baumer工业相机堡盟工业相机如何通过NEOAPISDK实现根据每次触发信号移动感兴趣区域ROI&#xff08;Python&#xff09; Baumer工业相机Baumer工业相机定序器功能的技术背景Baumer工业相机通过NEOAPI SDK使用定序器功能预期的相机动作测试的图像效果 Baumer工业相机通过NEOAPI S…

LoRA - 大型语言模型的低秩适应方法

人工智能咨询培训老师叶梓 转载标明出处 大规模预训练模型&#xff0c;如GPT-3&#xff0c;拥有高达1750亿参数&#xff0c;全参数微调不仅计算成本高昂&#xff0c;而且部署和维护多个微调实例变得非常困难。而且全参数微调需要大量的GPU内存&#xff0c;限制了同时训练的模型…

go 切片slice学习总结

切片的结构 切片的底层结构&#xff1a; type SliceHeader struct {Data uintptr // 指向底层数组的指针 Len int //长度Cap int //空间容量 } 切片的初始化 1 通过数组或者已有的slice创建新的slice 1.1 使用数组创建切片 通过数组的一部分来初始化切片。 …

fixed、absolute 和 relative 布局

https://andi.cn/page/621716.html

计算机视觉编程 1(图片处理)

目录 灰色度 缩略图 拷贝粘贴区域 调整图像尺寸 旋转图像45 画图线、描点 灰色度 灰度是指图像中每个像素的亮度值&#xff0c;用来描述图像中各个像素的明暗程度。在计算机视觉中&#xff0c;灰度可以通过以下方式来计算&#xff1a; 1. 平均值法&#xff1a;将图像中每…

核心技术揭秘:AI、低代码与定制开发的三重奏,如何应对复杂业务需求

背景介绍 在当今迅速发展的数字化时代&#xff0c;企业面临的业务环境变得日益复杂和多变。无论是面对不断变化的市场需求&#xff0c;还是处理海量数据并从中获取洞察力&#xff0c;企业都需要快速响应并灵活调整自身的策略。传统的开发模式在应对这种复杂性时往往显得力不从心…

大模型提示词工程技术2-设计有效的提示词技巧、角色与上下文在提示中的应用

大模型提示词工程技术2-设计有效的提示词技巧、角色与上下文在提示中的应用。《大模型提示词工程技术》的作者&#xff1a;微学AI&#xff0c;这是一本专注于提升人工智能大模型性能的著作&#xff0c;它深入浅出地讲解了如何通过优化输入提示词来引导大模型生成高质量、准确的…

技术赋能数字化转型:百数低代码平台在试点城市的应用与实践

在当今信息化高速发展的时代&#xff0c;数字化转型已成为城市和企业发展的必然趋势。为了推动这一进程&#xff0c;数字化转型城市试点政策应运而生。“据了解&#xff0c;中央财政将对每个试点城市给予1亿元资金奖补&#xff0c;支持中小企业实施数字化改造&#xff0c;以数字…

5 - ZYNQ GPIO

文章目录 0 前言1 GPIO基本概念1.1 MIO-EMIO基本介绍1.2 MIO-EMIO连接情况 0 前言 本文来参考博主徐晓康的博文 ZYNQ7000-GPIO详解&#xff0c;仅作为个人学习记录。 1 GPIO基本概念 在ZYNQ中&#xff0c;GPIO&#xff08;General Purpose Input/Output&#xff0c;通用输入…

嵌入式RTOS正在缩小与Linux系统之间的差异

RTOS与Linux的物联网设备操作系统之争已经持续了很多年。Linux以其强大的计算能力和丰富的软件生态,在需要复杂处理和软件支持的物联网设备上占据一席之地;RTOS凭借实时响应和资源节约的特性,在对实时性和资源占用有严格要求的场景中独领风骚。 如果时间倒回五年前,那…

[C++] C++11详解 (三)类的成员函数、完美转发

标题&#xff1a;[C] C11详解 &#xff08;三&#xff09;完美转发与lambda表达式 水墨不写bug 目录 一、C11新增两个类的默认成员函数 1.强制生成默认函数的关键字default: 2.禁止生成默认函数的关键字delete: 二、完美转发 正文开始&#xff1a; 一、C11新增两个类的默…

【YOLO5 项目实战】(8)PyQt5 图形界面—PCB缺陷检测系统

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【YOLO5 项目实战】&#xff08;8&#xff09;PyQt5 图形界面—PCB缺陷检测系统 1. PyQt5 图形界面开发工具1.1 PyQt5 的安装1.2 在 PyCharm 集成 QtDesigner 和 PyUIC1.3 使用 QtDesigner 开发 PyQt…

EPLAN在安装完成之后,输入文字时出现卡顿和死机的解决办法

EPLAN在安装完成之后,输入文字时出现卡顿和死机的解决办法 EPLAN在安装完成之后,插入文字时有时会卡顿,甚至出现软件卡死,无任何反映的情况,具体的解决办法可参考以下内容: 找到电脑右下角的输入法,右击进入设置, 如下图所示,点击进入常规设置, 如下图所示,向下找…

终于!我找到了开发的得力助手!阿里云天池云原生编程挑战赛参赛攻略

作者&#xff1a;ysevenk_7 参赛准备 我是机缘巧合在 6 月底了解到了天池云原生编程挑战赛&#xff0c;于是乎搜了一下&#xff0c;之前本人对于比赛并没有太多经验&#xff0c;看了大赛介绍之后莫名兴奋&#xff0c;果断拉了队友报名&#xff0c;完成认证、起队名、下载插件…

【STM32】RS485

RS485是常见的串口接口。 大部分图片来源&#xff1a;正点原子HAL库课程 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 目录 1 串口、UART、TTL、RS232、RS422、RS485的关系 1.1 串口 1.2 UART、TTL、RS232、RS422、RS485 1.3 常见串口标准的比较 …

Apache Arrow 的列式内存格式

Apache Arrow 的列式存储格式是一种内存数据组织标准&#xff0c;它通过物理布局、Array&#xff08;数组&#xff09;、Schema&#xff08;模式&#xff09;和 RecordBatch&#xff08;记录批次&#xff09;等&#xff0c;优化了大数据的存储与处理。这种格式以列而非行来存储…

更改网络ip地址时出现错误怎么办

在日常的网络使用中&#xff0c;‌有时我们需要更改IP地址以满足特定的网络需求&#xff0c;‌然而&#xff0c;‌在更改IP地址的过程中&#xff0c;‌可能会遇到各种错误&#xff0c;‌导致无法成功更改或网络连接出现问题。‌‌而更改网络IP地址时出现错误是由于多种原因导致…

二、基于Vue3的开发-环境搭建【Visual Studio Code】扩展组件

Visual Studio Code中的扩展组件 1、安装的扩展工具2、说明2.1 、代码规范性检查EsLint2.2 、代码语法高亮提示工具Vue - Official2.3 、阿里的AI代码开发提示工具 TONGYI Lingma 1、安装的扩展工具 2、说明 2.1 、代码规范性检查EsLint Visual Studio Code 中【设置】-setti…