TCP报文首部中存在一个RST位,如果该位被置1则表示这是个复位报文段。当一个报文段从一端发往一个不存在或者处于异常状态的另一端时,就会以一个复位报文段应答发送端,告知发送端连接出现错误,应当被关闭

有三种连接情况可能会产生复位报文段

  • 尝试连接到一个不存在的<ip,port>
  • 主动关闭的一方的套接字设置了SO_LINGER选项,并且超时时间为0
  • 另一端异常崩溃导致连接处于半关闭状态,此时正常的一端向已关闭的一端发送报文段

向不存在的端口发送连接请求

如果客户端尝试连接到port端口上而这个端口根本就没有服务器监听,那么当客户端发送三次握手的第一个SYN报文段时另一端会以复位报文段回应

可以在终端使用telnet ip port命令向

➜  ~ telnet localhost 9999
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
➜  ~ 

主动关闭的一方设置了SO_LINGER选项

SO_LINGER选项用于对连接关闭提供更多的控制,它影响的是close函数的行为。需要配合struct linger结构使用

struct linger
{int l_onoff;    // 开关选项int l_linger;   // 超时时间
};

使用方法为

struct linger so_linger;
so_linger.l_onoff = m;
so_linger.l_linger = n;
::setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));

根据上述设置的l_oneoff和l_linger不同,SO_LINGER有三种不同的行为

  • l_onoff = 0,表示关闭SO_LINGER选项,调用close函数时采用默认行为,即四次挥手,close立即返回
  • l_onoff != 0,l_linger = 0,表示开启SO_LINGER选项,调用close函数时不进行四次挥手而直接发送复位报文段给对端,close立即返回
  • l_onoff != 0,l_linger = 0,表示开启SO_LINGER选项,close函数变为阻塞函数,调用时会先将发送缓冲区中的数据全部发送出去并收到对端的ACK应答报文段(或者到达超时时间)再返回close函数。并且这种情况下不管套接字是否设置非阻塞close函数都会阻塞

通过wireshark观察报文段发送情况,客户端服务器的行为如下

  • 建立连接,客户端设置SO_LINGER选项并设置l_onoff != 0,l_linger = 0(上述第二种情况)
  • 0.5秒后客户端调用close函数终止连接
  • 服务器收到复位报文段后(read/recv返回-1)输出错误信息,并调用close函数终止连接

服务器输出错误信息

➜  server ./server
Connection reset by peer

复位报文段不需要对端应答,因为RST代表连接出现错误,双方只要各自关闭就可以了

半关闭连接情况下发送数据

在介绍保活定时器(KEEPALIVE)时提到过,如果通信双方的一端突然崩溃,会导致连接处于半关闭状态,也就是一端已经关闭,而另一端仍处于打开状态。在这种情况下,如果正常的一端向已关闭的一端发送数据,由于对端已经重启,丢失了所有连接信息,会返回一个复位报文段

借用<TCP/IP详解>中的例子,在连接正常的情况下断开服务器以太网电缆并重启,随后客户端发送数据

观察tcpdump结果

最终,服务器由于无法识别发来的连接,发送给客户端复位报文段以告知对方关闭连接

TCP/IP学习笔记(八)复位报文段相关推荐

  1. 【TCP/IP学习笔记1】 C语言讲解

    TCP/IP学习笔记(一) 一. TCP/IP结构:      TCP/IP是一个四层协议,结构如下:      1.应用层:各种应用程序和协议,如Http.FTP等.      2.传输层:TCP和 ...

  2. TCP/IP学习笔记(一)(转载)

    一.TCP/IP结构:      TCP/IP是一个四层协议,结构如下:      1.应用层:各种应用程序和协议,如Http.FTP等.      2.传输层:TCP和UDP      TCP提供一 ...

  3. TCP / IP学习笔记(9)-dns域名系统

    TCP / IP学习笔记(9)-dns域名系统 前面已经提到了访问一台机器要靠IP地址和MAC地址,其中,MAC地址可以通过ARP协议得到,所以这对用户是透明的,但是IP地址就不行,无论如何用户都需要 ...

  4. TCP/IP学习笔记(九)TCP报文段首部格式

    TCP为了实现稳定可靠的传输,自然是需要在发送数据时附带一些信息,对端接收到报文段后将用户数据分离开存放在接收缓冲区,然后根据附加信息决定接下来的行为.所以即使TCP是面向字节流的传输协议,但是传输的 ...

  5. TCP/IP学习笔记(五)TCP的保活定时器

    正常情况下,TCP连接的终止需要经历四次挥手阶段,体现在代码上就是某一端主动调用close函数关闭套接字,随后TCP向对端发送FIN位被置为1的报文段标志着连接的结束,同时对端响应应答报文段,并在随后 ...

  6. TCP/IP学习笔记(四)TCP超时重传及拥塞控制

    TCP是可靠的传输层协议,但这并不意味着一端发送的数据一定可以到达另一端,因为传输过程中遇到的情况是不可控的,很有可能就有某些数据发生丢失,所以"可靠"其实并不可靠. 不过毕竟现如 ...

  7. TCP/IP学习笔记(二)TCP三次握手

    TCP是一种面向连接的流传输协议,提供了对数据传输时的各种控制功能,比如 当丢包时可以重新发送 即使数据到达顺序错乱也可以保证数据的有序性 由于TCP是面向连接的协议,所以必须在确定通信对端存在时才会 ...

  8. TCP/IP学习笔记(3)----IP,ARP,RARP协议

    把这三个协议放到一起学习是因为这三个协议处于同一层(网络层协议),ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP ...

  9. TCP IP学习笔记① 互联网通信过程

    文章目录 一.TCP/IP和OSI模型 二.协议分层 2.1 物理层 2.2 数据链路层 2.2.1 以太网协议 2.2.2 MAC地址 2.2.4 广播 2.3 网际层 2.3.1 IP地址     ...

最新文章

  1. 007_html头部元素
  2. 获取height固定折叠元素真实高度方法
  3. mybatis知识点
  4. SonarQube的安装、配置与使用
  5. leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal | 106. 从中序后序遍历序列构造二叉树(Java)
  6. MySQL中int、char、varchar的性能浅谈
  7. [JavaWeb]Web概念概述
  8. webapp文本编辑器_Project Student:维护Webapp(可编辑)
  9. 非线性动力学_非线性动力学特辑 低维到高维的联通者
  10. centos7安装3.6版本zookeeper和jdk8
  11. 戴毅茹同济matlab,Stateflow系统建模(全)解读.pptx
  12. PAT 甲级 1004
  13. sqoop导出到mysql中文乱码问题总结、utf8、gbk
  14. kali工具中文手册_黑客系统指南-在安卓手机上安装kali分步教程
  15. java开发的程序怎么用_java安装后怎么使用?第一次编写java程序
  16. ie11 java提示升级,解决IE11安装升级失败和在安装前需要更新的问题
  17. 【V-REP自学笔记(六)】基于V-REP逆运动学模块的机械臂轨迹规划
  18. 【Java】学习日记 Day20
  19. 目标检测一阶段和二阶段对比图
  20. Linux系统安全加固指南(万字长文)

热门文章

  1. Java黑皮书课后题第3章:*3.17(游戏:剪刀、石头、布)编写可以玩流行的剪刀-石头-布游戏的程序
  2. 清原高中2021高考成绩查询,2021年抚顺高考状元是谁分数多少分,历年抚顺高考状元名单...
  3. Linux 下mysql5.7安装搬运 该安装说明坑最少
  4. [CQOI2018] 解锁屏幕
  5. nginx 全局配置
  6. linux下Intellij Idea 14的安装
  7. 操作系统实验报告16:CPU 调度
  8. php closure invoke,PHP Closure类详解
  9. [Python从零到壹] 三十五.图像处理基础篇之OpenCV绘制各类几何图形
  10. C# 系统应用之Cookie\Session基础知识及php读取Cookie\Session