测试本地Java Socket服务 curl报Connection reset by peer错误原因咨询
报错原因分析
核心原因是服务端的HTTP响应逻辑不符合HTTP/1.1协议规范,且连接关闭逻辑存在问题,具体可拆解为两点:
- 未返回
Content-Length响应头,curl无法判断响应体的结束位置
HTTP协议要求服务端必须通过Content-Length头明确告知客户端响应体的字节长度,或者使用Transfer-Encoding: chunked分块传输编码,否则客户端会一直等待读取数据直到连接关闭。你的代码仅返回了响应行和Content-Type头,没有标记响应体长度,curl无法判断hello,nio就是完整的响应内容,会继续等待后续数据。 - 服务端未读取客户端请求就直接强制关闭连接,触发TCP重置
HTTP/1.1默认开启Connection: keep-alive,curl发起请求时会先把完整的HTTP请求报文写入socket,之后等待响应。但你的代码逻辑是接收到socket连接后直接写响应,完全没有读取客户端发送的请求数据,写完响应后直接调用socket.close()关闭连接,此时客户端的请求数据可能还滞留在TCP缓冲区未被读取,服务端关闭连接时会发送RST报文而非正常的FIN四次挥手,curl收到RST后就会抛出Connection reset by peer的错误,但此时已经收到了之前传输过来的响应体内容,所以会同时输出报错和hello,nio。
可参考的修复方案
任选一种即可解决问题:
- 新增响应头明确告知客户端响应规则,修改service方法的响应头写入逻辑,增加两行配置:
printWriter.println("Content-Length: 9"); // hello,nio的UTF-8字节长度刚好为9 printWriter.println("Connection: close"); // 显式告知客户端响应结束后关闭连接 - 关闭连接前先读取socket输入流内的客户端请求内容,再执行关闭操作
- curl请求时指定使用HTTP/1.0协议,默认不开启keep-alive:
curl -0 http://localhost:8801
内容的提问来源于stack exchange,提问作者Nicolas Z
相关产品推荐
相关产品推荐

