当前位置: 首页> 科技> 名企 > 学懂C++(四十一):网络编程——深入详解 C++ 网络编程之 WebSocket 应用技术

学懂C++(四十一):网络编程——深入详解 C++ 网络编程之 WebSocket 应用技术

时间:2025/7/10 21:11:46来源:https://blog.csdn.net/martian665/article/details/141425379 浏览次数:0次

目录

一、引言

二、WebSocket 概念

1. WebSocket 概述

2. WebSocket 协议

WebSocket 握手请求示例

三、WebSocket 工作原理

四、WebSocket 的实现方式

1. 准备工作

2. WebSocket 服务器实现

服务器代码

3. WebSocket 客户端实现

客户端代码

五、总结


一、引言

        在现代互联网应用中,即时通信、实时数据传输和交互变得越来越重要。传统的 HTTP 协议由于其无状态和请求/响应模型的限制,难以满足这类需求。WebSocket 协议应运而生,提供了持久的双向通信通道。本文将深入解析 WebSocket 的概念、工作原理及其在 C++ 中的实现,并结合经典实例进行讲解。

二、WebSocket 概念
1. WebSocket 概述

        WebSocket 是一种全双工的通信协议,设计用于在 Web 浏览器和服务器之间进行实时、低延迟的双向通信。相较于传统的 HTTP 协议,WebSocket 协议具有以下几个显著特点:

  • 持久连接:一旦连接建立,客户端和服务器之间可以持续通信,避免了频繁的连接建立和关闭过程。
  • 低开销:减少了 HTTP 请求/响应头部的开销,适合高频率数据交换。
  • 双向通信:允许客户端和服务器随时发送数据,支持实时应用场景。
2. WebSocket 协议

        WebSocket 协议通过 HTTP/1.1 协议进行初始握手,然后升级到 WebSocket 协议。握手成功后,通信双方可以通过 TCP 连接进行双向数据传输。

WebSocket 握手请求示例
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

WebSocket 握手响应示例

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
三、WebSocket 工作原理

WebSocket 的工作流程主要包括以下几个步骤:

  1. 建立连接:客户端发起 HTTP 请求,包含特定的头部字段,用于请求将连接升级为 WebSocket 协议。
  2. 协议升级:服务器接收到请求后,返回相应的头部字段,确认升级为 WebSocket 协议。
  3. 数据传输:建立 WebSocket 连接后,客户端和服务器可以通过该连接进行双向数据传输,数据帧以二进制或文本格式传输。
  4. 关闭连接:任意一方可以随时关闭连接。
四、WebSocket 的实现方式

        WebSocket 的实现方式可以分为客户端和服务器两部分。在 C++ 中,可以使用开源的 WebSocket 库(如 libwebsocketsBoost.Beast)进行实现。本文将使用 Boost.AsioBoost.Beast 库来实现 WebSocket 客户端和服务器。

1. 准备工作

在开始编写代码之前,请确保已经安装了 Boost 库。可以从 Boost 官方网站下载并安装。

在 Linux 上

在基于 Debian 的系统(如 Ubuntu)上,可以使用以下命令安装 Boost 库:

sudo apt-get update sudo apt-get install libboost-all-dev
在 Windows 上

在 Windows 上,可以使用 vcpkg 或从 Boost 官网下载源码并手动编译安装。以下是使用 vcpkg 的示例:

  1. 下载并安装 vcpkg
  2. 使用 vcpkg 安装 Boost 库:
vcpkg install boost-asio boost-beast
2. WebSocket 服务器实现
服务器代码
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
using tcp = net::ip::tcp;               // from <boost/asio/ip/tcp.hpp>// 会话类
class session : public std::enable_shared_from_this<session> {websocket::stream<beast::tcp_stream> ws_;beast::flat_buffer buffer_;public:explicit session(tcp::socket socket): ws_(std::move(socket)) {}// 启动异步操作void run() {// 执行 WebSocket 握手ws_.async_accept(beast::bind_front_handler(&session::on_accept, shared_from_this()));}private:// WebSocket 握手的回调函数void on_accept(beast::error_code ec) {if (ec) {std::cerr << "accept: " << ec.message() << std::endl;return;}// 读取消息do_read();}// 读取消息void do_read() {ws_.async_read(buffer_, beast::bind_front_handler(&session::on_read, shared_from_this()));}// 读取消息后的回调函数void on_read(beast::error_code ec, std::size_t bytes_transferred) {if (ec == websocket::error::closed) {return;}if (ec) {std::cerr << "read: " << ec.message() << std::endl;return;}std::cout << "Received: " << beast::make_printable(buffer_.data()) << std::endl;buffer_.consume(buffer_.size()); // 清空缓冲区// 回应消息ws_.text(ws_.got_text());ws_.async_write(boost::asio::buffer("Echo: Hello from server"), beast::bind_front_handler(&session::on_write, shared_from_this()));}// 写消息后的回调函数void on_write(beast::error_code ec, std::size_t bytes_transferred) {if (ec) {std::cerr << "write: " << ec.message() << std::endl;return;}// 继续读取消息do_read();}
};// 监听器类
class listener : public std::enable_shared_from_this<listener> {net::io_context& ioc_;tcp::acceptor acceptor_;public:listener(net::io_context& ioc, tcp::endpoint endpoint) : ioc_(ioc), acceptor_(net::make_strand(ioc)) {beast::error_code ec;// 打开接收器acceptor_.open(endpoint.protocol(), ec);if (ec) {std::cerr << "open: " << ec.message() << std::endl;return;}// 绑定到端点acceptor_.bind(endpoint, ec);if (ec) {std::cerr << "bind: " << ec.message() << std::endl;return;}// 开始监听acceptor_.listen(net::socket_base::max_listen_connections, ec);if (ec) {std::cerr << "listen: " << ec.message() << std::endl;return;}}// 启动异步接受操作void run() {do_accept();}private:// 异步接受操作void do_accept() {acceptor_.async_accept(net::make_strand(ioc_), beast::bind_front_handler(&listener::on_accept, shared_from_this()));}// 接受连接后的回调函数void on_accept(beast::error_code ec, tcp::socket socket) {if (ec) {std::cerr << "accept: " << ec.message() << std::endl;} else {// 创建 WebSocket 会话std::make_shared<session>(std::move(socket))->run();}// 继续接受连接do_accept();}
};int main(int argc, char* argv[]) {try {if (argc != 2) {std::cerr << "Usage: websocket-server <port>\n";return EXIT_FAILURE;}// 解析命令行参数auto const port = static_cast<unsigned short>(std::atoi(argv[1]));// 创建 io_contextnet::io_context ioc{1};// 创建并启动监听器std::make_shared<listener>(ioc, tcp::endpoint{tcp::v4(), port})->run();// 运行 io_contextioc.run();} catch (const std::exception& e) {std::cerr << "Error: " << e.what() << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;
}

解析

  1. session 类:处理 WebSocket 会话,包括握手、读写消息等。
  2. listener 类:负责监听传入的 TCP 连接,并创建新的 WebSocket 会话。
  3. main 函数:解析命令行参数,创建 io_context,启动监听器并运行。

运行方式: 编译并运行服务器程序,例如:

在 Linux 上

假设将服务器代码保存为 websocket_server.cpp,使用以下命令进行编译和运行:

# 编译服务器代码
g++ -o websocket-server websocket_server.cpp -lboost_system -lboost_thread -lssl -lcrypto -lboost_beast# 运行服务器
./websocket-server 8080
在 Windows 上

假设将服务器代码保存为 websocket_server.cpp,使用以下命令进行编译和运行(需要安装 MinGW):

# 编译服务器代码
g++ -o websocket-server websocket_server.cpp -lboost_system -lws2_32 -lssl -lcrypto# 运行服务器
./websocket-server 8080

 

3. WebSocket 客户端实现
客户端代码
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <iostream>
#include <string>namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
using tcp = net::ip::tcp;               // from <boost/asio/ip/tcp.hpp>int main(int argc, char* argv[]) {try {if (argc != 3) {std::cerr << "Usage: websocket-client <host> <port>\n";return EXIT_FAILURE;}auto const host = argv[1];auto const port = argv[2];// 创建 io_contextnet::io_context ioc;// 解析地址tcp::resolver resolver(ioc);auto const results = resolver.resolve(host, port);// 创建 WebSocket 流websocket::stream<tcp::socket> ws{ioc};// 连接到服务器net::connect(ws.next_layer(), results.begin(), results.end());// 执行 WebSocket 握手ws.handshake(host, "/");// 发送消息ws.write(net::buffer(std::string("Hello from client")));// 读取响应beast::flat_buffer buffer;ws.read(buffer);std::cout << "Received: " << beast::make_printable(buffer.data()) << std::endl;// 关闭 WebSocket 连接ws.close(websocket::close_code::normal);} catch (const std::exception& e) {std::cerr << "Error: " << e.what() << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;
}

解析

  1. 解析命令行参数host 和 port
  2. 创建 io_context:管理 I/O 操作。
  3. 解析服务器地址:通过 tcp::resolver
  4. 创建 WebSocket 流:通过 websocket::stream<tcp::socket>
  5. 连接到服务器:通过 net::connect
  6. 执行 WebSocket 握手:通过 ws.handshake
  7. 发送消息:通过 ws.write
  8. 读取响应:通过 ws.read
  9. 关闭 WebSocket 连接:通过 ws.close

运行方式: 编译并运行客户端程序,例如:

在 Linux 上

假设将客户端代码保存为 websocket_client.cpp,使用以下命令进行编译和运行:

# 编译客户端代码
g++ -o websocket-client websocket_client.cpp -lboost_system -lboost_thread -lssl -lcrypto -lboost_beast# 运行客户端
./websocket-client localhost 8080
在 Windows 上

假设将客户端代码保存为 websocket_client.cpp,使用以下命令进行编译和运行(需要安装 MinGW):

# 编译客户端代码
g++ -o websocket-client websocket_client.cpp -lboost_system -lws2_32 -lssl -lcrypto# 运行客户端
./websocket-client localhost 8080

 

运行结果

Received: Echo: Hello from server
五、总结

        本文深入解析了 WebSocket 的基础概念、工作原理及其在 C++ 中的实现,并结合 Boost.AsioBoost.Beast 库实现了 WebSocket 服务器和客户端。通过详细的示例代码和解析,展示了如何在 C++ 中构建高效、实时的双向通信应用。希望本文能帮助读者更好地理解和掌握 WebSocket 技术及其在 C++ 中的应用,提高网络编程技能。

        本文提供的示例代码可以在 Linux 和 Windows 上运行,主要依赖于跨平台的 Boost.AsioBoost.Beast 库。无论您使用哪种操作系统,都需要确保系统上安装了相应的编译器和 Boost 库。通过本文的详细解释和示例,您应该能够在 C++ 环境中实现高效的 WebSocket 客户端和服务器。

关键字:学懂C++(四十一):网络编程——深入详解 C++ 网络编程之 WebSocket 应用技术

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: