调用read()读取HTTP请求时能否保证GET/POST/DELETE在同一次调用返回
问题解答
HTTP方法名能否保证单次read()完整返回
- 绝对不能认定GET、POST、DELETE等HTTP方法名一定会在同一次
read()调用中完整返回,方法名被拆分是完全合法且可能发生的情况 - TCP是无边界的字节流协议,
read()系统调用针对流式套接字的行为仅遵循POSIX规范:只要套接字接收缓冲区中至少有1字节可读,且无错误、无EOF触发,read()就可以返回结果,返回的字节数只和当前缓冲区可用字节数、你传入的读取缓冲区大小有关,和上层HTTP协议的语义边界没有任何关联。 - 常见触发拆分的场景包括:客户端分段发送请求数据、网络传输中出现IP分片、调用
read()时传入的缓冲区长度小于方法名字节数、内核接收缓冲区当前仅收到部分方法名字节等,极端场景下甚至可能出现每次read()仅返回1字节的情况。
5.11.0-36-generic内核版本的影响
- 你使用的5.11.0-36-generic版本Linux内核不会改变上述
read()的行为逻辑。 - 流式套接字的
read()行为是POSIX标准规定的基础语义,所有主流稳定版Linux内核都严格遵守该规则,从较早的2.6系列到最新的6.x系列,该行为从未发生过变更,不存在任何内核版本会保证HTTP方法名一次性完整返回的情况。
开发实践建议
处理HTTP请求时,必须在用户态维护独立的接收缓冲区,将每次read()拿到的字节追加到缓冲区中,再自行解析缓冲区内容判断是否已经收到完整的方法、请求行、请求头等语义单元,绝对不能依赖read()的返回边界做上层协议解析。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

