77 lines
3.0 KiB
Plaintext
77 lines
3.0 KiB
Plaintext
|
|
#ifndef TCP_SERVER_H
|
|||
|
|
#define TCP_SERVER_H
|
|||
|
|
|
|||
|
|
#include <boost/asio.hpp>
|
|||
|
|
#include <boost/crc.hpp>
|
|||
|
|
#include <vector>
|
|||
|
|
#include <string>
|
|||
|
|
#include <memory> // For std::enable_shared_from_this
|
|||
|
|
#include <cstdint> // For uint8_t, uint16_t, uint32_t
|
|||
|
|
// 使用 Boost.Asio 的命名空间
|
|||
|
|
using boost::asio::ip::tcp;
|
|||
|
|
// ---------------- CRC32 Declaration (使用 Boost.CRC) ----------------
|
|||
|
|
inline uint32_t calculate_crc32(const uint8_t* data, size_t length);
|
|||
|
|
// ---------------- Protocol Definition ----------------
|
|||
|
|
namespace proto {
|
|||
|
|
struct ProtocolConfig {
|
|||
|
|
static constexpr std::size_t kMagicLen = 4; // 魔数 4 字节
|
|||
|
|
static constexpr std::size_t kMsgTypeLen = 2; // 消息类型 2 字节
|
|||
|
|
static constexpr std::size_t kPayloadLenFieldLen = 4; // 载荷长度 4 字节
|
|||
|
|
static constexpr std::size_t kCrcLen = 4; // CRC 校验位 4 字节
|
|||
|
|
// 完整的头部长度 (Magic + MsgType + PayloadLenField)
|
|||
|
|
static constexpr std::size_t kHeaderLen = kMagicLen + kMsgTypeLen + kPayloadLenFieldLen; // 4 + 2 + 4 = 10 字节
|
|||
|
|
// 魔数常量
|
|||
|
|
static constexpr uint8_t kMagic[kMagicLen] = {0x62, 0x6e, 0x73, 0x00};
|
|||
|
|
};
|
|||
|
|
// 字节序转换函数声明
|
|||
|
|
inline uint16_t be16(const uint8_t* p);
|
|||
|
|
inline uint32_t be32(const uint8_t* p);
|
|||
|
|
inline void write_be16(uint8_t* p, uint16_t val);
|
|||
|
|
inline void write_be32(uint8_t* p, uint32_t val);
|
|||
|
|
|
|||
|
|
struct Message {
|
|||
|
|
uint16_t msg_type = 0; // 消息类型 2 字节
|
|||
|
|
std::vector<uint8_t> payload;
|
|||
|
|
uint32_t received_crc = 0; // 新增字段,用于存储接收到的CRC,方便调试
|
|||
|
|
};
|
|||
|
|
inline bool match_magic(const uint8_t* p);
|
|||
|
|
}
|
|||
|
|
// ---------------- Session Class (处理单个客户端连接) ----------------
|
|||
|
|
class session : public std::enable_shared_from_this<session> {
|
|||
|
|
public:
|
|||
|
|
explicit session(tcp::socket socket);
|
|||
|
|
void start();
|
|||
|
|
private:
|
|||
|
|
// 自定义缓冲区结构体
|
|||
|
|
struct ReceiveBuffer {
|
|||
|
|
static constexpr std::size_t capacity_ = 8192;
|
|||
|
|
uint8_t data_[capacity_];
|
|||
|
|
std::size_t read_idx = 0; // 已读到缓冲区的数据量 (读指针)
|
|||
|
|
std::size_t write_idx = 0; // 已处理/消耗的字节数 (写指针,指向下一个待处理字节)
|
|||
|
|
void compact();
|
|||
|
|
std::size_t data_size() const;
|
|||
|
|
std::size_t free_space() const;
|
|||
|
|
const uint8_t* current_data() const;
|
|||
|
|
uint8_t* write_ptr();
|
|||
|
|
} receive_buffer_;
|
|||
|
|
void do_read_some();
|
|||
|
|
void parse_messages();
|
|||
|
|
std::string payload_to_ascii_string(const std::vector<uint8_t>& payload);
|
|||
|
|
std::string bytes_to_hex_string(const uint8_t* data, std::size_t len);
|
|||
|
|
void on_message(proto::Message msg);
|
|||
|
|
// 修改原有的 send_response 为更通用的 send_message
|
|||
|
|
void send_message(uint16_t msg_type, const std::vector<uint8_t>& payload);
|
|||
|
|
tcp::socket socket_;
|
|||
|
|
};
|
|||
|
|
// ---------------- TCPServer Class ----------------
|
|||
|
|
// 这个类负责监听端口并接受新的客户端连接
|
|||
|
|
class TCPServer {
|
|||
|
|
public:
|
|||
|
|
TCPServer(boost::asio::io_context& io_context, uint16_t port);
|
|||
|
|
private:
|
|||
|
|
void do_accept();
|
|||
|
|
tcp::acceptor acceptor_;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#endif // SERVER_H
|