树莓派C语言实现Web服务器快速刷新页面报broken pipe错误如何解决
排查方向
1. 快速验证修复:忽略SIGPIPE信号
SIGPIPE信号的默认处理动作是终止进程,触发原因是进程向已经被对端关闭的socket文件描述符执行写操作。你可在服务初始化阶段(main函数开头位置)添加代码忽略该信号,避免进程直接崩溃:
#include <signal.h> // 放在main函数初始化逻辑最前面 signal(SIGPIPE, SIG_IGN);
忽略信号后,写关闭的socket时write()会返回-1,且errno设置为EPIPE,你只需处理该返回值即可。
2. 完善socket读写错误处理逻辑
- 所有
write()/send()调用必须校验返回值,当返回值为-1时,若errno为EPIPE、ECONNRESET等连接异常错误,直接关闭当前socket fd、清理该连接对应的资源,终止当前连接处理流程,不要继续执行后续写操作 - 你gdb调用栈中显示
write的入参nbytes=0,需额外检查响应长度计算逻辑:是否存在请求解析错误、读静态资源失败时,未做判断直接将响应长度赋值为0的异常情况
3. 校验连接关闭时序逻辑
- 检查
read()操作的返回值:当read()返回0时代表对端(浏览器)已经主动断开连接,此时需要立刻终止当前连接的处理,不要走到后续发送响应的逻辑 - 确认每个连接处理完成后,socket fd是否被正确、仅关闭一次,避免出现野fd被后续逻辑误用的情况
4. 排查线程池任务队列逻辑
- 校验是否存在同一个连接fd被多次投递到任务队列的情况,避免多个线程并发操作同一个fd,出现其中一个线程已经关闭fd、另一个线程还在执行写操作的问题
- 确认任务队列中的fd在取出执行前,是否做了有效性校验
内容的提问来源于stack exchange,提问作者logsInMyEyes69
相关产品推荐
相关产品推荐

