14-TCP 协议(连接异常与RST)

1. RST 段

当 TCP连接出现严重的错误时,必须释放连接。通过将 TCP 首部中的 RST 标志位置 1,就可以通知对端发生错误,以终止连接。

我们在 TCP 协议(连接异常)一文中已经看到过这种错误,当时实验演示的是向一个不存在的端口建立连接,导致对端发送过来一个 RST 段。

2. 异常终止连接

正常情况下,关闭连接的方式是发送 FIN 段,即四次挥手。这种方式也称为有序释放(orderly release)。

也可以通过发送 RST 段给对端来释放连接,这种方式称为异常释放(abortive release)。

异常终止连接有两个特点:

  • 丢弃任何尚未发送的数据,立即发送 RST 报文段
  • RST 接收方会区分另一端是异常关闭还是正常关闭,从而做出不同响应

3. 实验——观察异常关闭

使用 unp/protocol/tools/winclient/tcp_client.cpp 程序,让其在关闭套接字时不发送 FIN 段,而是 RST 段给对端。

3.1 实验步骤

  • Linux 端启动 unp/protocol/tools/tcpserver/serv.c(需要编译)
$ ./serv 192.168.80.130 5000
  • win7 上打开 OmniPeek 开始抓包(选择 VMnet8 网卡)

  • win7 启动 tcp_client.exe,指定选项 SO_LINGER,发起异常关闭请求

给套接字指定 SO_LINGER 选项,客户端在 close 的时候会发送 RST 段而不是正常的 FIN 段。


这里写图片描述
图1 启动客户端并输入以上字符

3.2 实验结果

我们在服务器端看到如下信息:


这里写图片描述
图2 服务器端打印 Connection reset by peer

抓包结果如图 3.


这里写图片描述
图3 OmniPeek 抓取的数据

可以看到,客户端 (192.168.80.2) 最后一次发送了一个 RST 段给服务器。服务器收到 RST 段后,在执行 read 的时候出错,打印 Connection reset by peer(图 2).

还有几点需要注意:

  • 服务器端并没有给这个 RST 回复 ACK(任何收到 RST 段的一方根本不会为这个 RST 进行确认)。
  • 主动发送 RST 段的一方,不会进入 TIME_WAIT 状态。

4. 总结

  • RST 的含义
  • 知道接收方对 RST 是如何响应的