socket:read: Connection reset by peer

推荐文章:https://winddoing.github.io/post/33577.html#%E8%BF%94%E5%9B%9E%E5%80%BC-n-x3D-x3D-0
socket:read: Connection reset by peer_第1张图片

推荐文章:https://blog.csdn.net/hguisu/article/details/38700899
今天线上服务器报错 Connection reset by peer ,为了一探究竟,所以来复现一下当时的场景。

示例代码

server 伪代码

server.listen("127.0.0.1",1234)
clientSock = server.accept()
whilt true{
	msg = clientSock.recv()
	print(msg)
	sleep(1)
	serverMsg = "server say" + rand.int()
	clientSock.send(serverMsg)
}

client伪代码

sock = createSocket()
sock.connect("127.0.0.1",1234)
while true{
	clientMsg = "client say" + rand.int()
	sock.send(clientMsg)
	sleep(2)
	msg = sock.recv()
	print(msg)
}

执行结果

具体代码有不同实现方式,但是过程都是上面的形式,我这里使用lua调用底层c++。
server
socket:read: Connection reset by peer_第2张图片
client
在这里插入图片描述
服务器先开起来,然后客户端连接上去,在服务器调用完send之后,立刻把server进程杀掉。
这个时候执行send把数据发送到tcp待发送缓冲区中,接下来client执行 recv方法的时候就会报错 Connection reset by peer。

Wireshark抓包验证

socket:read: Connection reset by peer_第3张图片
使用Wireshark进行抓包,可以看到在1584处向server发送了 ctl+c 命令,杀掉了进程,那么这是进程就交由Linux 0号进程管理(所有进程的父进程);0号进程对其进行资源回收,向client发送了 FIN 结束请求,收到client ACK 回复之后 server最后向client socket发送了 RST 消息,此时客户端再去 recv 的时候就会报 “socket:read: Connection reset by peer” 错误。

TCP RST消息的三种情况:

  1. 访问不存在的端口。若端口不存,则直接返回RST,同时RST报文接收通告窗口大小为0。其实客户端向服务器的某个端口发起连接,如果端口被处于TIME_WAIT 状态的连接占用时,客户端也会收到RST
  2. 异常终止连接。一方直接发送RST报文,表示异常终止连接。一旦发送方发送复位报文段,发送端所有排队等待发送的数据都被丢弃。应用程序可以通过socket选项SO_LINGER来发送RST复位报文。
  3. 处理半打开连接。一方关闭了连接,另一方却没有收到结束报文(如网络故障),此时另一方还维持着原来的连接。而一方即使重启,也没有该连接的任何信息。这种状态就叫做半打开连接。而此时另一方往处于半打开状态的连接写数据,则对方回应RST复位报文。

RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。

你可能感兴趣的:(计算机网络,网络协议,tcp,tcp/ip)