-
Notifications
You must be signed in to change notification settings - Fork 1
NET_SocketConnection
SweerItTer edited this page Feb 21, 2026
·
1 revision
SocketConnection 是 Socket 连接管理类,负责单个客户端 TCP 连接的生命周期管理。专注连接处理,命令解析和执行委托给 TcpServer。
class SocketConnection : public std::enable_shared_from_this<SocketConnection> {
public:
SocketConnection(int clientFd, uint64_t clientId,
const std::string& clientIp, uint16_t clientPort,
std::weak_ptr<TcpServer> server);
~SocketConnection();
// 禁止拷贝,允许移动
SocketConnection(const SocketConnection&) = delete;
SocketConnection& operator=(const SocketConnection&) = delete;
SocketConnection(SocketConnection&& other) noexcept;
SocketConnection& operator=(SocketConnection&& other) noexcept;
// 连接控制
void startReceiveLoop();
void stopReceiveLoop();
void disconnect();
// 数据发送
bool send(const DataPacket& packet);
// 状态查询
uint64_t getClientId() const;
const std::string& getClientIp() const;
uint16_t getClientPort() const;
ConnectionState getState() const;
bool isValid() const;
// 文件描述符
int getFd() const;
// 统计信息
uint64_t getReceivedBytes() const;
uint64_t getSentBytes() const;
const std::string& getLastError() const;
private:
void receiveLoop();
void sendLoop();
void setKeepAliveOptions();
bool sendText(const std::string& data);
bool sendFd(int fd);
std::pair<std::string, std::string> parseReceivedData(const std::string& data);
};SocketConnection(int clientFd, uint64_t clientId, const std::string& clientIp, uint16_t clientPort, std::weak_ptr server)
描述: 构造 Socket 连接对象。
参数:
-
clientFd: 客户端 socket 文件描述符 -
clientId: 客户端唯一 ID -
clientIp: 客户端 IP 地址 -
clientPort: 客户端端口号 -
server: 服务器弱引用(用于回调,通过weak_ptr.lock()安全访问)
示例:
// 通常由 TcpServer 通过工厂函数创建,无需手动调用
// TcpServer::createConnection() 为私有成员函数
// 内部会使用 shared_from_this() 获取有效的 shared_ptr
auto conn = server->createConnection(clientFd, clientId, "192.168.1.100", 12345);描述: 析构函数,自动关闭连接并清理资源。
描述: 启动接收循环(非阻塞,在独立线程中运行)。
行为:
- 创建接收线程
- 持续监听客户端数据
- 解析命令并委托给 TcpServer 执行
- 发送响应给客户端
示例:
conn->startReceiveLoop();描述: 停止接收循环。
行为:
- 停止接收线程
- 清空发送队列
- 断开连接
示例:
conn->stopReceiveLoop();描述: 断开连接。
行为:
- 关闭 socket
- 清理资源
- 通知服务器
描述: 发送数据(异步,进入发送队列)。
参数:
-
packet: 数据包
返回值:
-
true: 数据已加入发送队列 -
false: 发送失败(队列满或连接已断开)
支持的数据类型:
-
PacketType::TEXT: 普通文本 -
PacketType::DMABUF_FD: DMA-BUF(零拷贝) -
PacketType::RAW_FD: 裸文件描述符
示例:
// 发送文本
conn->send(DataPacket::createText("Hello"));
// 发送 DMA-BUF(零拷贝)
DmaBufferPtr dmabuf = DmaBuffer::create(1920, 1080, DRM_FORMAT_ARGB8888);
conn->send(DataPacket::createDmaBuf(dmabuf));描述: 获取客户端 ID。
返回值: 客户端唯一 ID
描述: 获取客户端 IP 地址。
返回值: IP 地址字符串
描述: 获取客户端端口号。
返回值: 端口号
描述: 获取连接状态。
返回值: 连接状态枚举
状态值:
-
ConnectionState::CONNECTED: 已连接 -
ConnectionState::DISCONNECTED: 已断开 -
ConnectionState::ERROR: 错误状态
描述: 检查连接是否有效。
返回值:
-
true: 连接有效 -
false: 连接无效
描述: 获取 socket 文件描述符。
返回值: socket fd
描述: 获取接收的字节数统计。
返回值: 总接收字节数
描述: 获取发送的字节数统计。
返回值: 总发送字节数
描述: 获取最后的错误信息。
返回值: 错误信息字符串
接收线程
├─ recv() 阻塞等待数据
├─ 解析命令(格式:COMMAND PARAMS)
├─ 委托给 TcpServer::executeCommand
├─ 发送响应给客户端
└─ 循环
发送线程
├─ 从发送队列取数据
├─ 类型判断
│ ├─ TEXT -> send()
│ ├─ DMABUF_FD -> sendmsg() + SCM_RIGHTS
│ └─ RAW_FD -> sendmsg() + SCM_RIGHTS
└─ 循环
TCP Keep-Alive 选项用于检测死连接:
-
TCP_KEEPIDLE: 空闲 60 秒后开始探测 -
TCP_KEEPINTVL: 每 10 秒探测一次 -
TCP_KEEPCNT: 最多探测 5 次
// TcpServer 内部自动创建和管理 SocketConnection
// 无需手动创建和销毁
// 访问连接信息
uint64_t clientId = conn->getClientId();
std::string ip = conn->getClientIp();
uint16_t port = conn->getClientPort();
// 发送数据
conn->send(DataPacket::createText("Hello"));
// 断开连接
conn->disconnect();if (conn->isValid() && conn->getState() == ConnectionState::CONNECTED) {
// 连接有效
conn->send(DataPacket::createText("Ping"));
} else {
// 连接无效
std::cout << "Connection error: " << conn->getLastError() << std::endl;
}std::cout << "Client: " << conn->getClientIp() << ":" << conn->getClientPort() << std::endl;
std::cout << "Received: " << conn->getReceivedBytes() << " bytes" << std::endl;
std::cout << "Sent: " << conn->getSentBytes() << " bytes" << std::endl;Client: GETFILENAME /path/to/file.txt
void SocketConnection::parseReceivedData(const std::string& data) {
if (data.empty() || !server_) {
return;
}
// 解析命令格式: COMMAND PARAMS
std::string command;
std::string params;
size_t spacePos = data.find(' ');
if (spacePos != std::string::npos) {
command = data.substr(0, spacePos);
params = data.substr(spacePos + 1);
} else {
command = data;
params = "";
}
// 委托给 TcpServer 执行命令
std::string commandResult = server_->executeCommand(clientId_, command, params);
// 发送响应
if (!commandResult.empty()) {
sendText(commandResult + "\n");
}
}std::string TcpServer::executeCommand(uint64_t clientId,
const std::string& command,
const std::string& params) {
auto commandHandler = commandHandler_.lock();
if (!commandHandler) {
return ""; // Command handler expired
}
return commandHandler->executeCommand(clientId, command, params);
}std::string CommandHandler::executeCommand(uint64_t clientId,
const std::string& command,
const std::string& params) {
std::lock_guard<std::mutex> lock(registryMutex_);
auto it = commandRegistry_.find(command);
if (it == commandRegistry_.end()) {
return ""; // Command not found
}
try {
return it->second.callback(clientId, command, params);
} catch (const std::exception& e) {
fprintf(stderr, "[CommandHandler] Exception: %s\n", e.what());
return std::string("ERROR: ") + e.what();
}
}当连接断开时:
- 接收线程自动退出
- 发送队列清空
- 状态更新为
DISCONNECTED - 服务器收到通知并移除客户端
通过 getLastError() 获取详细错误信息:
if (!conn->send(DataPacket::createText("Hello"))) {
std::cerr << "Send failed: " << conn->getLastError() << std::endl;
}- 接收线程: 独立线程,处理接收和命令解析
- 发送线程: 独立线程,处理发送队列
- 线程安全: 使用互斥锁保护共享数据(状态、队列等)
- 异步发送: 数据进入队列立即返回,不阻塞调用者
- 零拷贝: DMA-BUF 直接发送,无需内存拷贝
- 批量处理: 发送队列支持批量处理,减少系统调用
- TcpServer - TCP 服务器
- CommandHandler - 命令处理器
- DataPacket - 数据包类型
主页
API 文档
DMA 模块
DRM 模块
- DRM 模块总览
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- PlanesCompositor - DRM 平面合成器
- DrmBpp - DRM 格式定义
NET 模块
- NET 模块总览
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接管理
- CommandHandler - 命令处理器
- DataPacket - 数据包
V4L2 模块
- V4L2 模块总览
- CameraController - V4L2 摄像头控制器
- Frame - V4L2 帧数据结构
- FormatTool - V4L2 格式工具
- Exception - V4L2 异常类
V4L2Param 模块
- V4L2Param 模块总览
- ParamControl - 参数控制
- ParamLogger - 参数日志
- ParamProcessor - 参数处理器
RGA 模块
- RGA 模块总览
- RgaConverter - RGA 转换器
- RgaProcessor - RGA 处理器
- FormatTool - RGA 格式工具
MPP 模块
- MPP 模块总览
- EncoderContext - 编码器上下文
- EncoderCore - 编码器核心
- JpegEncoder - JPEG 编码器
- StreamWriter - 流写入器
- MppResourceGuard - MPP 资源守护
- FileTools - 文件工具
- FormatTool - 格式工具
Sys 模块
- Sys 模块总览
- CpuMonitor - CPU 监控器
- MemoryMonitor - 内存监控器
- Base - 基础类
Mouse 模块
- Mouse 模块总览
- Watcher - 鼠标监视器
Utils 模块
- Utils 模块总览
- AsyncThreadPool - 异步线程池
- ConcurrentQueue - 并发队列
- FdWrapper - 文件描述符包装器
- FenceWatcher - 围栏监视器
- FixedSizePool - 固定大小对象池
- Logger - 日志记录器
- ObjectsPool - 对象池
- OrderedQueue - 有序队列
- ProgressBar - 进度条
- SafeQueue - 安全队列
- SharedBufferState - 共享缓冲区状态
- SimpleVariant - 简单变体类型
- ThreadPauser - 线程暂停器
- ThreadUtils - 线程工具
- Types - 类型定义
- UdevMonitor - Udev 监视器