【C++】在Windows中使用Boost库——实现TCP、UDP通信
目录
一、编译Boost库
二、TCP服务端
三、TCP客户端
四、UDP连接
一、编译Boost库
1. 先去官网下载Boost库源码
2. 点击下载最新的版本
下载Windows环境的压缩包,然后解压
3. 在解压后的目录路径下找到“bootstrap.bat”
打开控制台,在“bootstrap.bat”的路径下输入
.\bootstrap.bat
执行完成后,就会在当前目录生成一个可执行文件 b2.exe
4. 直接运行“b2.exe”。
编译好后,其默认的安装路径为当前目录下的stage\lib
文件夹内
而头文件就在下载当前目录的boost
目录里面。
5. 打开VS编辑器并加载工程,点击“项目-》属性”
在“包含目录”中点击“编辑”
添加包含目录如下
在“库目录”中点击“编辑”
添加库目录如下
6. 添加后使用一段测试代码看看是否有报错,能否通过编译
#include<iostream>
#include"boost/asio.hpp"
using namespace std;
using namespace boost;
using asio::ip::tcp;int main() {cout << "server start ……" << endl;asio::io_context io;tcp::acceptor acptr(io, tcp::endpoint(tcp::v4(), 6688));tcp::socket sock(io);acptr.accept(sock);cout << "client:" << sock.remote_endpoint().address() << endl;try {while (true) {char buf[0xFF];sock.receive(asio::buffer(buf));sock.send(asio::buffer(buf));}}catch(std::exception& e) {cout << e.what();}sock.close();::system("pause");
}
二、TCP服务端
基于 Boost.Asio 库实现简单 TCP 服务器的代码如下。
实现功能:该服务器可以接受多个客户端的连接,接收客户端发送的数据,并将客户端发送的数据回传给客户端。当客户端断开连接时,服务器会检测到并打印信息。
头文件(TCPServer_ByBoost.h):
#pragma once
#include <iostream>
#include <boost/asio.hpp>using boost::asio::ip::tcp;class TCPServer {
public:TCPServer(short port) : acceptor(io_context, tcp::endpoint(tcp::v4(), port)) {//初始化acceptor成员变量,acceptor是一个tcp::acceptor类型的对象,它使用io_context和一个tcp::endpoint对象进行初始化。//tcp::endpoint对象表示服务器要监听的地址和端口,这里使用tcp::v4()表示 IPv4 地址,端口号由传入的参数port决定。//io_context是 Boost.Asio 的输入输出上下文,用于管理异步操作。startAccept(); //接受客户端的连接请求}~TCPServer() {io_context.stop(); //停止io_context的运行,以确保所有异步操作都能正确结束。}void startAccept();void handleClient(tcp::socket& socket);private:boost::asio::io_context io_context;tcp::acceptor acceptor;
};
源文件(TCPServer_ByBoost.cpp)
#include "TCPServer_ByBoost.h"void TCPServer::startAccept() { //startAccept()用于开始接受客户端连接tcp::socket socket(io_context); //创建一个tcp::socket对象socket,并使用io_context进行初始化。acceptor.async_accept(socket, [this, &socket](const boost::system::error_code& error) { //使用acceptor.async_accept异步接受客户端连接。这个方法会在有客户端连接时调用传入的回调函数。回调函数接受一个boost::system::error_code类型的参数error,用于表示是否有错误发生。if (!error) {tcp::endpoint clientEndpoint = socket.remote_endpoint();std::cout << "Client: " << std::string(clientEndpoint.address().to_string()) + ":" + std::to_string(clientEndpoint.port()) + " connected" << std::endl; //打印客户端的ip和端口std::thread clientThread([this, &socket]() {handleClient(socket);});clientThread.detach(); //使用detach方法将线程分离,使其在后台独立运行,不等待线程结束}startAccept();});io_context.run(); //io_context.run()启动io_context的事件循环,处理异步操作}void TCPServer::handleClient(tcp::socket& socket) { //handleClient()用于处理与单个客户端的通信char buffer[1024];while (true) {boost::system::error_code error;tcp::endpoint clientEndpoint = socket.remote_endpoint();size_t length = socket.read_some(boost::asio::buffer(buffer), error); //使用socket.read_some异步读取数据到buffer中。这个方法会在有数据可读时读取一部分数据,并返回读取的字节数。如果发生错误,将错误码存储在error中if (error == boost::asio::error::eof) { //客户端关闭了连接std::cout << "Client: " << std::string(clientEndpoint.address().to_string()) + ":" + std::to_string(clientEndpoint.port()) + " closed" << std::endl;break;}else if (error) { //其它错误std::cerr << "Error reading from client: " << error.message() << std::endl;break;}else {buffer[length] = '\0';std::cout << std::string(clientEndpoint.address().to_string()) + ":" + std::to_string(clientEndpoint.port()) + " Received: " << std::string(buffer) << std::endl;boost::asio::write(socket, boost::asio::buffer(buffer, length));}}socket.close(); //关闭与客户端的连接}
调用:
#include"TCPServer_ByBoost.h"int main() {try {TCPServer server(8888);}catch (const std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}return 0;
}
运行结果:
三、TCP客户端
基于 Boost.Asio 库实现简单 TCP 客户端的代码如下。
实现功能:客户端定时向服务端发送数据,同时能够异步接收服务端发送来的数据。
头文件(TCPClient_ByBoost.h):
#pragma once
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>using boost::asio::ip::tcp;class TCPClient {
public:TCPClient(const std::string& serverAddress, short serverPort) : io_context(), socket(io_context) { //接受服务器地址和端口号作为参数tcp::resolver resolver(io_context); //创建一个tcp::resolver对象,用于解析服务器地址和端口号,得到连接服务器的端点列表tcp::resolver::results_type endpoints = resolver.resolve(serverAddress, std::to_string(serverPort));boost::asio::connect(socket, endpoints); //使用boost::asio::connect连接到服务器的其中一个端点startReceive(); //开始异步接收服务端数据};void sendMessage(const std::string& message); //接受一个字符串参数,表示要发送给服务器的消息void startReceive();
private:boost::asio::io_context io_context;tcp::socket socket;boost::asio::streambuf receiveBuffer;
};
源文件(TCPClient_ByBoost.cpp)
#include "TCPClient_ByBoost.h"void TCPClient::sendMessage(const std::string& message) { //接受一个std::string类型的参数message,表示要发送给服务器的消息内容。boost::asio::write(socket, boost::asio::buffer(message)); //使用boost::asio::write函数将给定的消息写入到客户端的socket中,从而实现向服务器发送消息的功能
};void TCPClient::startReceive() {async_read(socket, receiveBuffer, boost::asio::transfer_at_least(1), //使用async_read函数异步读取数据,只要接收到至少1个字节的数据就会触发回调[this](const boost::system::error_code& error, std::size_t bytes_transferred) { //回调函数接受两个参数,const boost::system::error_code& error表示是否有错误发生,std::size_t bytes_transferred表示读取的字节数。if (!error) {std::cout << "Raw buffer content: ";std::istreambuf_iterator<char> eos;std::string bufferContent(std::istreambuf_iterator<char>(&receiveBuffer), eos);std::cout << bufferContent << std::endl;startReceive(); // 继续接收下一条消息}else {std::cerr << "Error receiving data: " << error.message() << std::endl;}});boost::thread ioThread([this]() { io_context.run(); }); //创建一个新的线程ioThread,在线程中运行io_context的事件循环。这样可以确保异步读取操作能够在后台持续进行ioThread.detach(); //使用detach方法将线程分离,使其在后台独立运行
}
调用:
#include"TCPClient_ByBoost.h"int main() {try {TCPClient client("127.0.0.1", 8888);while (true) {// 在主线程中定期向服务器发送消息,不会被接收数据阻塞client.sendMessage("Hello from client.");boost::this_thread::sleep_for(boost::chrono::seconds(5));}}catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}return 0;
}
运行结果:
四、UDP连接
基于 Boost.Asio 库实现简单 UDP 连接的代码如下。
实现功能:可以接受多个连接,接收到数据后会将接收的数据回传。
头文件(UDP_ByBoost.h)
#pragma once#include <iostream>
#include <boost/asio.hpp>using boost::asio::ip::udp;class UDPServer {
public:UDPServer(short port) : socket(io_context, udp::endpoint(udp::v4(), port)) {startReceive();}~UDPServer() {io_context.stop();}void startReceive();void startSend(std::size_t length);private:boost::asio::io_context io_context;udp::socket socket;udp::endpoint remote_endpoint;char buffer[1024];
};
源文件(UDP_ByBoost.cpp)
#include "UDP_ByBoost.h"void UDPServer::startReceive() {socket.async_receive_from(boost::asio::buffer(buffer), remote_endpoint, //socket.async_receive_from异步接收数据。当有数据到达时,回调函数会被调用。[this](const boost::system::error_code& error, std::size_t bytes_transferred) {if (!error) {std::cout << "Received from " << remote_endpoint.address().to_string() << ":" << remote_endpoint.port() << std::endl;std::cout << "Received data: " << buffer << std::endl;startSend(bytes_transferred);}else {std::cerr << "Error receiving data: " << error.message() << std::endl;}startReceive();});io_context.run();
}void UDPServer::startSend(std::size_t length) {socket.async_send_to(boost::asio::buffer(buffer, length), remote_endpoint, //socket.async_send_to异步发送数据回给客户端。当数据发送完成后,回调函数会被调用。[this](const boost::system::error_code& error, std::size_t bytes_sent) {if (!error) {std::cout << "Sent data back to " << remote_endpoint.address().to_string() << ":" << remote_endpoint.port() << std::endl;}else {std::cerr << "Error sending data: " << error.message() << std::endl;}});
}
调用:
#include"UDP_ByBoost.h"int main() {try {UDPServer server(12345);}catch (const std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}return 0;
}
运行结果
相关文章:

【C++】在Windows中使用Boost库——实现TCP、UDP通信
目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包,然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台,在“bootstrap.…...

怎么提取pdf的某一页?批量提取pdf的某一页的简单方法
怎么提取pdf的某一页?在日常工作与学习中,我们经常会遇到各式各样的PDF文件,它们以其良好的兼容性和稳定性,成为了信息传输和存储的首选格式。然而,在浩瀚的文档海洋中,有时某个PDF文件中的某一页内容尤为重…...

Github优质项目推荐(第八期)
文章目录 Github优质项目推荐 - 第八期一、【manim】,66.5k stars - 创建数学动画的 Python 框架二、【siyuan】,19.5k stars - 个人知识管理软件三、 【GetQzonehistory】,1.3k stars - 获取QQ空间发布的历史说说四、【SecLists】࿰…...
快读快写模板
原理 众所周知,在c中,用putchar和getchar输入输出字符的速度是很快的,因此,我们可以考虑把数字转化为字符,按位输出;把字符读入后转化为数字的每一位。 该快读快写可以实现对所有整数类型的输入。 templ…...
make_blobs函数
make_blobs 是 scikit-learn 库中用于生成聚类(或分类)数据集的函数。它通常用于生成多个高斯分布的簇状数据,以便进行分类或聚类算法的测试和验证。make_blobs 非常灵活,可以控制簇的数量、样本数量、每个簇的标准差、中心点等参…...

特斯拉Optimus:展望智能生活新篇章
近日,特斯拉举办了 "WE ROBOT" 发布会,发布会上描绘的未来社会愿景,让无数人为之向往。在这场吸引全球无数媒体的直播中,特斯拉 Optimus 人形机器人一出场就吸引了所有观众的关注。从多家媒体现场拍摄的视频可以看出来&…...

基于Leaflet和SpringBoot的全球国家综合检索WebGIS可视化
目录 前言 一、Java后台程序设计 1、业务层设计 2、控制层设计 二、WebGIS可视化实现 1、侧边栏展示 2、空间边界信息展示 三、标注成果展示 1、面积最大的国家 2、国土面积最小的国家 3、海拔最低的国家 4、最大的群岛国家 四、总结 前言 在前面的博文中ÿ…...
【Linux】/usr/share目录
在Linux和类Unix操作系统中,/usr/share 目录是一个用于存放共享数据文件的目录。这个目录遵循Filesystem Hierarchy Standard (FHS),它定义了Linux系统中文件和目录的组织结构。/usr 代表 “user”,而 share 表示这些文件可以被系统上的多个用…...
Java中如何应用序列化 serialVersionUID 版本号呢?
文章目录 示例1:没有 serialVersionUID 的类输出结果:示例2:类修改后未定义 serialVersionUID可能出现的问题:示例3:显式定义 serialVersionUID总结最佳实践推荐阅读文章 为了更好地理解 serialVersionUID 的使用&…...

面部识别技术:AI 如何识别人脸
在科技飞速发展的今天,面部识别技术已经广泛应用于各个领域,从手机解锁到安防监控,从金融支付到门禁系统,面部识别技术正在改变着我们的生活方式。那么,AI 究竟是如何识别人脸的呢?让我们一起来揭开面部识别…...
全面解析文档对象模型(DOM)及其操作(DOM的概念与结构、操作DOM节点、描述DOM树的形成过程、用DOMParser解析字符串为DOM对象)
1. 引言 文档对象模型(DOM)是Web开发中的核心概念,它提供了一种结构化的方法来表示和操作HTML和XML文档。通过DOM,开发者可以动态地访问和更新文档的内容、结构和样式。本文将深入探讨DOM的概念与结构、操作DOM节点的方法、DOM树…...
字符串使用方法:
字符串: -- 拼接字符串 SELECT CONCAT(糯米,啊啊啊撒,删掉); -- 字符长度 SELECT LENGTH(asssssssggg); -- 转大写 SELECT UPPER(asdf); -- 转小写 SELECT LOWER(ASDFG); -- 去除左边空格 SELECT LTRIM( aaaasdrf ); -- 去除右边空格 SELECT RTRIM( aaaasdff ); -- 去除两端…...

想让前后端交互更轻松?alovajs了解一下?
作为一个前端开发者,我最近发现了一个超赞的请求库 alovajs,它真的让我眼前一亮!说实话,我感觉自己找到了前端开发的新大陆。大家知道,在前端开发中,处理 Client-Server 交互一直是个老大难的问题ÿ…...

E/MicroMsg.SDK.WXMediaMessage:checkArgs fail,thumbData is invalid 图片资源太大导致分享失败
1、微信分享报: 2、这个问题是因为图片太大导致: WXWebpageObject webpage new WXWebpageObject();webpage.webpageUrl qrCodeUrl;//用 WXWebpageObject 对象初始化一个 WXMediaMessage 对象WXMediaMessage msg new WXMediaMessage(webpage);msg.tit…...

No.21 笔记 | WEB安全 - 任意文件绕过详解 part 3
(一)空格绕过 原理 Windows系统将文件名中的空格视为空,但程序检测代码无法自动删除空格,使攻击者可借此绕过黑名单限制。基于黑名单验证的代码分析 代码未对上传文件的文件名进行去空格处理,存在安全隐患。相关代码逻…...

咸鱼自动发货 免费无需授权
下载:(两个都可以下,自己选择) https://pan.quark.cn/s/1e3039e322ad https://pan.xunlei.com/s/VO9ww89ZNkEg_Fq1wRr-fk9ZA1?pwd8x9s# 不是闲管家 闲鱼自动发货(PC端) 暂不支持密,免费使…...

Netty核心组件
1.Channel Channel可以理解为是socket连接,在客户端与服务端连接的时候就会建立一个Channel,它负责基本的IO操作(binf()、connect()、rad()、write()等); 1.1 Channel的作用 通过Channel可获得当前网络连接的通道状态…...

Windows中如何安装SSH
主要内容 一、参考资料二、主要过程法一:通过「设置」安装法二:使用 PowerShell进行安装在 Windows 中配置 OpenSSH 服务器过程截图 一、参考资料 Windows10 打开ssh服务,报错“The service name is invalid ” windows开启ssh服务教程 在 W…...

在linux上部署ollama+open-webu,且局域网访问教程
在linux上部署ollamaopen-webu,且局域网访问教程 运行ollamaopen-webui安装open-webui (待实现)下一期将加入内网穿透,实现外网访问功能 本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具,并使用Op…...

基于大模型的招聘智能体:从创意到MVP
正在考虑下一个 SaaS 创意?以下是我在短短几个小时内从创意到 MVP 的过程。 以下是我将在这篇文章中介绍的内容概述: 为什么这个想法让我产生共鸣我是如何开始构建它的我现在的处境以及我是否会真正推出 获得 SaaS 创意并构建它并不容易。就是这样。 …...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...