197 lines
5.4 KiB
Markdown
197 lines
5.4 KiB
Markdown
# Socket通信现代化改进总结
|
||
|
||
## 改进内容
|
||
|
||
本次改进对原有的Unix Socket通信机制进行了全面重构,实现了更加现代化、结构化的双向通信协议,并添加了**实时监听终端窗口大小变化**的功能。
|
||
|
||
## 主要特性
|
||
|
||
### 1. 结构化消息协议
|
||
|
||
- **消息头设计**:采用固定16字节的消息头,包含魔数、类型、载荷长度
|
||
- **魔数验证**:使用 `0x42534D54` ("BSMT") 作为魔数,确保协议正确性
|
||
- **类型安全**:明确定义消息类型枚举,避免混淆
|
||
|
||
### 2. 实时窗口大小监听
|
||
|
||
- **信号驱动**:使用 `SIGWINCH` 信号捕获终端窗口大小变化
|
||
- **条件变量唤醒**:使用 `pthread_cond_t` 实现高效的事件驱动等待
|
||
- **零延迟响应**:信号触发时立即唤醒处理线程,无需轮询
|
||
- **独立线程**:专门的监控线程处理窗口事件,不阻塞主流程
|
||
- **自动同步**:窗口大小变化时自动发送更新消息给服务端
|
||
|
||
### 3. 双向通信
|
||
|
||
- **客户端 → 服务端**:初始化消息、窗口大小更新
|
||
- **服务端 → 客户端**:响应消息、关闭通知
|
||
- **并发处理**:使用多线程/goroutine 同时处理双向消息
|
||
|
||
### 4. 线程安全
|
||
|
||
- 使用 `pthread_mutex` 保护共享资源
|
||
- 使用 `sig_atomic_t` 处理信号标志
|
||
- Go 端使用 channel 控制 goroutine 生命周期
|
||
|
||
## 文件变更
|
||
|
||
### 新增文件
|
||
|
||
1. **`src/socket_protocol.h`** - 协议定义头文件
|
||
- 消息类型枚举
|
||
- 消息头结构
|
||
- 终端信息结构
|
||
- 函数声明
|
||
|
||
2. **`src/socket_protocol.c`** - 协议实现
|
||
- `write_message()` - 发送结构化消息
|
||
- `read_message()` - 读取结构化消息
|
||
- `free_message_payload()` - 释放消息载荷
|
||
|
||
3. **`tests/test_window_resize.c`** - 窗口大小测试程序
|
||
- 演示实时窗口监听功能
|
||
- 交互式测试工具
|
||
|
||
4. **`SOCKET_PROTOCOL.md`** - 协议文档
|
||
- 详细的协议说明
|
||
- 使用示例
|
||
- 架构设计文档
|
||
|
||
### 修改文件
|
||
|
||
1. **`src/client.c`** - 完全重构
|
||
- 添加 SIGWINCH 信号处理器
|
||
- 实现窗口监控线程
|
||
- 使用新的消息协议
|
||
- 添加响应监听线程
|
||
|
||
2. **`internal/services/tasks/socket.go`** - Go服务端重构
|
||
- 实现新的消息读写函数
|
||
- 添加消息类型常量
|
||
- 实现窗口大小更新监听
|
||
- 优化错误处理
|
||
|
||
3. **`Makefile`** - 更新编译规则
|
||
- 添加 `socket_protocol.o` 依赖
|
||
- 添加新测试目标
|
||
|
||
## 使用方法
|
||
|
||
### 编译
|
||
|
||
```bash
|
||
cd execve_hook
|
||
make clean
|
||
make
|
||
|
||
# 编译测试程序
|
||
make test_window_resize
|
||
```
|
||
|
||
### 测试窗口大小监听
|
||
|
||
1. 启动Go服务端:
|
||
```bash
|
||
cd go_service
|
||
sudo ./build/bash_go_service-amd64 daemon
|
||
```
|
||
|
||
2. 运行测试程序:
|
||
```bash
|
||
cd execve_hook
|
||
./build/test_window_resize
|
||
```
|
||
|
||
3. 在程序运行时调整终端窗口大小
|
||
|
||
4. 观察服务端日志输出窗口大小更新信息
|
||
|
||
### 开启调试模式
|
||
|
||
```bash
|
||
make DEBUG=1
|
||
make test_window_resize
|
||
```
|
||
|
||
## 技术亮点
|
||
|
||
### 1. 现代C编程实践
|
||
|
||
- 使用 `pthread` 多线程
|
||
- 使用 `pthread_cond_t` 条件变量实现事件驱动
|
||
- 使用 `sigaction` 处理信号(而非过时的 `signal`)
|
||
- 使用 `clock_gettime` 实现带超时的条件等待
|
||
- 结构化错误处理
|
||
- 内存管理规范(malloc/free配对)
|
||
|
||
### 2. 高效的消息序列化
|
||
|
||
- 使用二进制协议,避免文本解析开销
|
||
- 固定头部 + 可变载荷设计
|
||
- 支持零拷贝传输(直接读写buffer)
|
||
|
||
### 3. 并发模型
|
||
|
||
- **C端**:
|
||
- 主线程:发送初始消息
|
||
- 窗口监控线程:监听 SIGWINCH 信号(**条件变量驱动**)
|
||
- 响应监听线程:接收服务端消息
|
||
- 输入监听线程:捕获键盘和鼠标事件
|
||
|
||
- **Go端**:
|
||
- 主 goroutine:处理业务逻辑
|
||
- 监听 goroutine:接收客户端更新消息
|
||
|
||
### 4. 协议扩展性
|
||
|
||
设计的消息类型枚举支持轻松添加新消息类型:
|
||
|
||
```c
|
||
typedef enum {
|
||
MSG_TYPE_INIT = 1,
|
||
MSG_TYPE_WINDOW_SIZE_UPDATE = 2,
|
||
MSG_TYPE_SERVER_RESPONSE = 3,
|
||
MSG_TYPE_CLOSE = 4,
|
||
// 可以继续添加新类型...
|
||
MSG_TYPE_HEARTBEAT = 5,
|
||
MSG_TYPE_FILE_TRANSFER = 6,
|
||
// ...
|
||
} MessageType;
|
||
```
|
||
|
||
## 性能考虑
|
||
|
||
- **窗口监听**:使用条件变量实现事件驱动,零 CPU 占用等待,即时响应
|
||
- **输入监听轮询间隔**:100ms,平衡响应性和 CPU 使用
|
||
- **消息大小**:终端信息约 60-80 字节,网络开销小
|
||
- **内存使用**:动态分配,用完即释放
|
||
- **线程数量**:固定 4 个线程(C端),不会无限增长
|
||
|
||
## 兼容性
|
||
|
||
- **Linux内核**: 2.6+(支持SIGWINCH信号)
|
||
- **Glibc**: 2.17+(pthread支持)
|
||
- **Go版本**: 1.16+
|
||
|
||
## 未来优化方向
|
||
|
||
1. **去重机制**:连续相同窗口大小不重复发送
|
||
2. **批量更新**:合并短时间内的多次变化
|
||
3. **心跳机制**:检测连接状态
|
||
4. **压缩传输**:对大载荷使用压缩
|
||
5. **加密通信**:添加消息加密层
|
||
6. ~~**条件变量优化**~~:✅ 已完成 - 使用 `pthread_cond_t` 替代轮询
|
||
|
||
## 测试覆盖
|
||
|
||
- ✓ 基本消息收发
|
||
- ✓ 窗口大小监听
|
||
- ✓ 多线程并发
|
||
- ✓ 异常断开处理
|
||
- ✓ 大载荷传输
|
||
- ⚠ 压力测试(待完善)
|
||
- ⚠ 内存泄漏检测(待完善)
|
||
|
||
## 总结
|
||
|
||
本次改进将原有的简单socket通信升级为现代化的、可扩展的双向通信机制。通过采用结构化协议、多线程设计和信号驱动机制,实现了实时监听终端窗口大小变化的功能,为后续更多实时交互特性奠定了基础。
|