web模块介绍-网络socket篇-含QA
Web框架Socket模块设计与实现
模块概述
Socket模块是整个Web框架的网络通信基础,采用面向对象的设计方式,实现了TCP网络通信的完整功能。
类结构设计
1. 基础Socket类 (socket.h)
- 提供统一的接口:bind、listen、connect、accept等
- 实现了多个socket优化配置选项
2. 服务端Socket和客户端Socket
- 继承于socket基类
- 对业务进行针对性简化
3. Socket处理器 (socket_handler.h)
- 内置epoll和服务器监听句柄(服务器唯一实例)
- 内部提供handler接口对新连接执行处理(获取工厂实例,assign任务)
常见问题解答(Q&A)
Q1: 项目中使用了epoll进行IO多路复用,为什么选择epoll而不是select/poll?epoll的EPOLLONESHOT标志位的作用是什么?
A1: 这个问题可以从以下几个方面回答:
-
epoll相比select/poll的优势:
- select/poll每次调用都需要将fd集合从用户态拷贝到内核态,而epoll通过mmap实现内核与用户空间的共享内存
- select/poll都需要遍历整个fd集合,而epoll采用回调机制,只关注发生事件的fd
- select最大支持1024个fd,poll没有限制但性能会随fd数量增长而下降,epoll则基本不受限制
-
在代码中EPOLLONESHOT的使用:
1 | void SocketHandler::attach(int sockfd) { |
EPOLLONESHOT确保一个socket连接在任意时刻只被一个线程处理,防止多线程下的并发问题。
Q2: 项目中ServerSocket的构造函数中设置了多个socket选项,请解释这些选项的作用及其对性能的影响。
A2: 参考 server_socket.cpp
中的实现:
- set_recv_buffer/set_send_buffer : 设置10KB的收发缓冲区,用于调节数据传输的缓冲大小
- set_linger : 控制socket关闭时的行为,设置为true且timeout为0表示立即关闭
- set_keepalive : 保持连接活跃,定期检测连接状态
- set_reuseaddr : 允许地址重用,服务器重启时可以立即绑定端口
Q3: 项目中如何处理socket的异常情况?比如客户端异常断开、连接超时等。
A3: 主要通过以下机制处理:
- epoll事件监控:
1 | if (m_epoll.is_set(i, EPOLLHUP)) { |
- 资源清理:
- 使用TaskFactory管理连接对应的任务
- 及时清理断开的连接
- 完善的错误日志记录
Q4: 项目中Socket模块使用了哪些设计模式?为什么要使用这些模式?
A4: 主要使用了以下设计模式:
- 单例模式:SocketHandler采用单例模式,确保全局只有一个socket管理器
- 工厂模式:TaskFactory负责创建和管理任务
- 策略模式:通过继承Socket基类实现ServerSocket和ClientSocket,提供不同的连接策略
Q5: 项目如何保证长连接的稳定性?如何处理心跳检测?
A5: 主要通过以下机制实现:
- keepalive机制:
1 | bool Socket::set_keepalive() { |
- 超时检测:
- 通过epoll的timeout参数实现超时检测
- 配合TaskFactory管理连接状态
- 异常情况及时清理资源
评论