我正在尝试调试一些嵌入式设备在通过无线方式下载固件并过早关闭连接时遇到的问题,无法获取所有数据。
我尝试使用 curl 和 wget 下载文件,但下载没有任何问题并且校验和匹配。
我能找到的唯一“提示”是当我使用详细选项 (-v) 运行 curl 时。我创建了一个包含虚拟内容的文件,其中只多次包含单词 dummy。
当我运行时,curl -v http://myserver/dummy.txt
我收到以下响应:
dummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummClosing connection #0 ydummydummydummydummydummydummydummydummydummydummydummydummydummy
为什么在数据结束之前会出现“关闭连接#0”?
apache 版本是 2.2,我们在它前面也有 HAProxy,但如果我在机器上本地进行 curl ,我会遇到同样的“问题”。
答案1
TLDR:您所看到的只是终端上的显示伪影,并不表明您的 Web 服务器或 HAproxy 过早关闭连接存在任何问题。
我认为这带有输出缓冲的反直觉效应。
Linux glibc 的默认行为是行缓冲当标准输出发送到 TTY 时。这将缓冲输出,并且仅在以下任一情况下在终端上显示数据块:
- 观察到行尾
- 输出缓冲区已满
- 程序终止。
如果“关闭连接”消息被发送到立即显示的标准错误但是 URL 中的最后一点内容只有在 curl 终止时才会从缓冲区中出来。
当你使用以下命令更改缓冲时,你可能会看到更直观、更连续的结果stdbuff
并使错误和输出模式无缓冲:
stdbuf -o0 -e0 curl -v http://myserver/dummy.txt
但是当您更改数据以包含更多换行符时:
dummy
dummy
dummy
...