目录
一、编译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;
}
运行结果