一、Socket创建和连接

C++网络编程(asio)

文章目录

  • C++网络编程(asio)
  • 1、Asio概述
  • 2、网络编程基本流程
    • 2、创建socket
    • 3、创建监听socket
    • 4、绑定accpet监听套接字
    • 5、连接指定的端点
    • 6、服务器接收连接

点击查看代码

1、Asio概述

​ Asio起源于Boost库,是一款专为网络I/O定时器串行端口通信设计的库,提供了同步和异步的编程模型,用以简化网络和低级I/O的操作。asio封装了操作系统一些底层机制如select、socket、poll/epoll等,以实现异步IO模型

Asio异步处理,可以使任务触发时不需要等待,继续往下执行其他任务,直至其它线程将处理完成,并回调通知此线程。

普通的网络编程,通常是指使用传统的系统调用和同步阻塞的方式进行网络通信,可以看看代码:
点击进入
其中的accept、recv、listen等函数默认是同步/阻塞的。

下面将使用Boost.Asio库对网络编程进行重写

2、网络编程基本流程

服务器端

  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 : 发收信息

请添加图片描述## 1、创建终端节点

概念:所谓终端节点就是用来通信的端对端的节点,可以通过ip地址和端口构造,其他节点可以连接这个终端节点做通信.

客户端,我们可以通过对端(服务器端)的ip和端口构造一个endpoint,用这个endpoint和其通信。

int client_end_point() {
	std::string raw_ip_address = "127.0.0.1";
	unsigned short port_num = 3333;
	boost:system::error_code ec; // 错误码
	// asio提供转换地址
	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 Address. Error code = " 
			<< ec.value() << ". Message is " << ec.message();
		return ec.value();
	}

	// bind(ip+address)
	asio::ip::tcp::endpoint ep(ip_address, port_num);
	return 0;
}

此时,ep 对象表示客户端端点,可以用于连接指定的服务器上的 TCP。然而,代码并没有显示实际连接过程或与服务器的任何通信,因此它只是为将来使用而准备端点。

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

int server_end_point()
{
	unsigned short port_num = 3333;
	// 服务器将监听主机上的所有可用 IPv6 地址
	asio::ip::address ip_address = asio::ip::address_v6::any();
	asio::ip::tcp::endpoint ep(ip_address, port_num);
	return 0;
}

此时,ep 对象表示一个可以用于监听传入连接请求的 TCP 端点,其 IP 地址为所有可用的 IPv6 地址,而端口号由函数参数 port_num 决定。

2、创建socket

服务器和客户端socket一致,创建socket分为4步,

  1. 创建上下文io_context
  2. 选择协议
  3. 生成socket
  4. 打开socket
int create_tcp_socket()
{
	// 上下文告诉socket,此socket为ioc服务
	asio::io_context ioc;
	// IPV4的TCP协议
	asio::ip::tcp protocol = asio::ip::tcp::v4();
	asio::ip::tcp::socket socket(ioc);
	boost::system::error_code ec;

	socket.open(protocol, ec);
	if (ec.value() != 0) {
		std::cout 
			<< "Failed to open the socket. Error code = " 
			<< ec.value() << ". Message is " << ec.message();
	}

	return 0;
}

这段代码演示了如何使用 Boost.Asio 库来创建并打开一个 TCP 套接字

3、创建监听socket

服务端,我们还需要生成一个acceptorsocket,用来监听接收新来自客户端的连接

int create_acceptor_socket()
{
	asio::io_context ioc;
	asio::ip::tcp::acceptor a(ioc, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 3333));
	return 0;
}

这段代码演示了如何使用 Boost.Asio 库来创建并打开一个监听套接字,用于接受传入的连接请求。监听套接字通常用于服务器端,用于等待客户端的连接。

4、绑定accpet监听套接字

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

  • 创建端点(ip+端口)。
  • 创建监听套接字acceptor
  • 绑定监听套接字acceptor
int bind_acceptor_socket()
{
	unsigned short port_num = 3333;
	asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(), port_num);
	asio::io_context ioc;
	asio::ip::tcp::acceptor acceptor(ioc, ep.protocol());
	boost::system::error_code ec;
	acceptor.bind(ep, ec);
	if (ec.value() != 0) {
		std::cout
			<< "Failed to bind the acceptor socket. Error code = "
			<< ec.value() << ". Message is " << ec.message();
	}
	return 0;
}

这段代码展示了如何使用 Boost.Asio 库创建一个绑定到指定 IP 地址和端口的监听套接字,用于等待客户端的连接请求。

5、连接指定的端点

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

  • 创建端点(ip+端口)。
  • 创建通信socket套接字。
  • 通信socket套接字连接到指定端点。
int connect_to_end()
{
	std::string raw_ip_address = "192.168.1.124";
	unsigned short port_num = 3333;
	try
	{
		asio::ip::tcp::endpoint ep(asio::ip::address::from_string(raw_ip_address), port_num);
		asio::io_context ioc;
		asio::ip::tcp::socket socket(ioc, ep.protocol());
		socket.connect(ep);
	}
	catch (system::system_error &e)
	{
		std::cout << "Error connect! Error code = " << e.code()
			<< ". Message: " << e.what();
		return e.code().value();
	}
	return 0;
}

这段代码用于在客户端创建套接字并连接到服务器,以便与服务器进行数据交换。

6、服务器接收连接

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

  • 创建端点(ip+端口)。
  • 创建监听套接字acceptor
  • 绑定监听套接字acceptor
  • 监听队列大小。
  • 创建与客户端通信套接字。
  • 接收客户端连接。
int accept_int_connection()
{
	// 缓冲来不及接收的信息
	const int BACKLOG_SIZE = 30;
	unsigned short port_num = 3333;
	asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(), port_num);
	asio::io_context ioc;
	try
	{
		asio::ip::tcp::acceptor acceptor(ioc, ep.protocol());
		acceptor.bind(ep);
		acceptor.listen(BACKLOG_SIZE);
		asio::ip::tcp::socket socket(ioc);
		acceptor.accept(socket);
	}
	catch (system::system_error& e)
	{
		std::cout << "Error accept! Error code = " << e.code()
			<< ". Message: " << e.what();
		return e.code().value();
	}
	return 0;
}

这段代码用于在服务器端创建接受套接字,绑定端点并开始监听连接请求,然后处理下一个连接请求并与客户端建立连接,以便进行数据交换。


参考:
恋恋风辰blog
森明帮大于黑虎帮
哔哩哔哩

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超详解——python条件和循环——小白篇

目录 1. 缩进和悬挂else 2. 条件表达式 3. 和循环搭配的else 4. 可调用对象 总结&#xff1a; 1. 缩进和悬挂else 在Python中&#xff0c;代码块是通过缩进来表示的。条件判断和循环结构的代码块需要正确缩进。悬挂else指的是else子句和相应的if或循环在同一级别的缩进。 …

AVL树 ---(C++)

本篇讲全面的讲解 AVL 树的插入&#xff0c;旋转以及验证 AVL 树的性能&#xff08;本篇未实现删除代码&#xff09;。至于为什么会有 AVL 树&#xff0c;这是因为简单的二叉搜索树并不能直接的保证搜索的效率&#xff0c;因为当我们在二叉搜索树中插入一段有序的序列的时候&am…

STC90C51驱动LCD1602、LCD12864、OLED

主控芯片&#xff08;STC90C516RDPG5151028&#xff09;介绍 ROM64K,RAM1280字节&#xff0c;40Pin&#xff0c;3个定时器&#xff0c;1个串口&#xff0c;8个中断源&#xff08;分别是&#xff1a;外部中断0(INTO)、外部中断 1(INT1)、外部中断 2(INT2)、外部中断 3(INT3)、定…

【微信小程序开发(从零到一)】——个人中心页面的实战项目(二)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

「动态规划」如何计算能获得多少点数?

740. 删除并获得点数https://leetcode.cn/problems/delete-and-earn/description/ 给你一个整数数组nums&#xff0c;你可以对它进行一些操作。每次操作中&#xff0c;选择任意一个nums[i]&#xff0c;删除它并获得nums[i]的点数。之后&#xff0c;你必须删除所有等于nums[i] …

【网络安全的神秘世界】web应用程序安全与风险

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 第一章&#xff1a;web应用程序安全与风险 web攻击基础知识 1、什么是web应用攻击 web攻击的本质&#xff0c;就是通过http协议篡改应用程序&#xff0…

虚拟机ping不通主机,但是主机可以ping通虚拟机

我在Windows10系统安装了虚拟机&#xff0c;设置的主机与虚拟机的连接方式是桥接&#xff0c;安装好后&#xff0c;发现虚拟机ping不通主机&#xff0c;但是主机可以ping通虚拟机。 我的操作是&#xff1a;关闭防火墙&#xff0c;发现虚拟机可以ping通主机了。说明是Windows10…

python后端结合uniapp与uview组件tabs,实现自定义导航按钮与小标签颜色控制

实现效果&#xff08;红框内&#xff09;&#xff1a; 后端api如下&#xff1a; task_api.route(/user/task/states_list, methods[POST, GET]) visitor_token_required def task_states(user):name_list [待接单, 设计中, 交付中, 已完成, 全部]data []color [#F04864, …

CPP初级:模板的运用!

目录 一.泛型编程 二.函数模板 1.函数模板概念 2.函数模板格式 3.函数模板的原理 三.函数模板的实例化 1.隐式实例化 2.显式实例化 3.模板参数的匹配原则 四.类模板 1.类模板的定义格式 2.类模板的实例化 一.泛型编程 泛型编程&#xff1a;编写与类型无关的通用代码…

express入门01服务器搭建以及get和post请求的监听

微搭提供了后端API的能力&#xff0c;但是不同的版本收费差别巨大&#xff0c;因为使用的门槛限制了中小企业使用低代码平台。那可不可以既要又要呢&#xff1f;答案是肯定的&#xff0c;那其实掌握一定的后端框架&#xff0c;借助我们在低代码中已经熟练掌握的技能其实是比较容…

2024.6.9 七

Python的time库 先导入库 import time相关函数 time.time() 返回当前时间的时间戳(一个记录时间的浮点数),从1970年开始算的 time.localtime(sec) 返回一个指定时间戳(sec)的struct_time对象,是一个元组封装起来的,默认是当地时间 struct_time对象 tm_year 年 tm_mon 月 tm_…

CDR2024软件破解Keygen激活工具2024最新版

CorelDRAW Graphics Suite2024最新版&#xff0c;这是一款让我爱不释手的图形设计神器&#xff01;作为一个软件评测专家&#xff0c;我一直在寻找一款能够提升我的设计效率和创造力的工具。而这款软件&#xff0c;简直就是为我量身定制的&#xff01;&#x1f389; 「CorelDR…

算法金 | AI 基石,无处不在的朴素贝叶斯算法

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 历史上&#xff0c;许多杰出人才在他们有生之年默默无闻&#xff0c; 却在逝世后被人们广泛追忆和崇拜。 18世纪的数学家托马斯贝叶斯…

温度传感器十大品牌

温度传感器品牌排行榜-十大热电偶品牌-热敏电阻品牌排行-Maigoo品牌榜

TikTok Shop账号需要防关联吗?

在TikTokShop作为新兴的电商销售渠道中&#xff0c;保护账号的安全和隐私&#xff0c;防止账号关联成为了重要的任务。为了更好地理解为何需要防关联以及如何进行防范&#xff0c;让我们深入探讨一下这个问题。 为什么要防关联&#xff1f; 1. 账号异常风险&#xff1a;防关联…

电容十大品牌供应商

十大电容器品牌&#xff0c;电解电容-陶瓷电容-超级电容器品牌排行榜-Maigoo品牌榜

Android gradle kts 8.0以上版本配置签名和修改APK输出名字

目录 概述修改签名配置新建签名文件目录配置签名信息使用签名信息打包 修改APK名称 概述 之前写过一篇文章是通过Kotlin的Dsl结合gradle编写的插件来管理项目依赖&#xff0c;我是从一个开源项目叫DanDanPlayAndroid项目上学到的&#xff0c;那时还没有使用toml文件来管理项目…

Linux入门学习(2)

1.相关复习新的指令学习 &#xff08;1&#xff09;我们需要自己创建一个用户&#xff0c;这个用户前期可以是一个root用户&#xff0c;后期使用创建的普通用户 &#xff08;2&#xff09;文件等于文件内容加上文件属性,对于文件的操作就包括对于文件内容的操作和文件属性&…

Apache SeaTunnel社区5月月报更新!

各位热爱 SeaTunnel 的小伙伴们&#xff0c;社区 5 月份月报来啦&#xff01; SeaTunnel 正在迅猛发展&#xff0c;积极投入社区项目建设的小伙伴将促进SeaTunnel不断提升数据同步的高可扩展性、高性能及高可靠性。欢迎关注每月月报更新&#xff0c;期待在下个月的Merge Star月…

Redis持久化说明

Redis的持久化是指将内存中的数据持久化到磁盘中&#xff0c;以保证数据在重启或宕机后不会丢失。 Redis提供了两种主要的持久化方式&#xff1a;RDB(Redis DataBase)和AOF(Append Only File)。 RDB&#xff08;Redis DataBase&#xff09; 1、RDB快照原理 RDB持久化方式会定…