TCP通信 - RST的产生

Posted 流水灯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP通信 - RST的产生相关的知识,希望对你有一定的参考价值。

 产生RST介绍的原因

1、请求超时

有89、27两台主机。主机89向主机27发送了一个SYN,表示希望连接8888端口,主机27回应了主机89一个SYN表示可以连接。但是主机89莫名其妙的发送了一个RST表示我不想连接你了。经过排查发现,在主机89上的程序在建立了socket之后,用setsockopt的SO_RCVTIMEO选项设置了recv 的超时时间为100ms。而抓包结果表示,从主机89发出SYN到接收SYN的时间多达110ms。因此主机89上的程序认为接收超时,所以发送了RST拒绝进一步发送数据。

 

2、接收缓冲区还有数据未被读出

当close断开连接时,如果缓冲区中又未被读取的数据,则TCP协议规定不会发送正常的FIN包,而发送RST给对端,接收缓冲区的数据丢失

 

3、端口未打开

主机241向主机114发送一个SYN请求,表示想要连接主机114的40000端口,但是主机114上根本没有打开40000这个端口,于是就向主机241发送了一个RST

 

4、server端调用close()之后,client端write

当server端close套接字的时候,假设此时server端的接受缓冲区没有数据了。则close发送的是FIN,client端如果收到FIN之后,调用read函数,是返回0的,因为FIN的接收,表明client端以后再无数据可以接收,因为对方发来FIN,就表明对方不在发送数据了。然后client发送应答ack报文,表明收到FIN报文,server收到ack报文之后,就进去了FIN_WAIT_2阶段,根据tcp协议,向一个 FIN_WAIT2 状态的服务 TCP(已 ACK 响应 FIN 分节)写入数据不成问题,所以此时我们可以在client端调用write函数,写入client端的发送缓冲区,由tcp连接,发送到server的接收缓冲区。但是此时,由于server端已经关闭了socket(Socket.close()方法的语义和TCP的“FIN”标志语义不一样:发送TCP的“FIN”标志表示我不再发送数据了,而Socket.close()表示我不再发送也不接受数据了),所以此时的接收缓冲区的内容都被抛弃,同时server端返回RST。

  收到RST的client端,如果调用read函数,读取,是返回RST错误的

  如果我们的client对这个RST错误,不采取处理,继续调用write,会发生epipe错误。这种情况一般发生在客户进程不理会(或未及时处理)Socket 错误,继续向服务 TCP 写入更多数据时,内核将向客户进程发送 SIGPIPE 信号,该信号默认会使进程终止(此时该前台进程未进行 core dump)。所以,向一个 FIN_WAIT2 状态的服务 TCP(已 ACK 响应 FIN 分节)写入数据不成问题,但是写一个已接收了 RST 的 Socket 则是一个错误。

 

5、keepalive 超时

 

 

RST介绍

1. 发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓冲区中的包,发送RST。

2. 而接收端收到RST包后,也不必发送ACK包来确认。

以上是关于TCP通信 - RST的产生的主要内容,如果未能解决你的问题,请参考以下文章

简单理解TCP通信的三次握手

ESP8266 STA TCP 客户端配置并连接通信

TCP通信程序

基于TCP协议的网络通信

unp第七章补充之socket tcp 产生 rst响应的情况

网络编程--02 TCP