《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(2)-读书笔记
章节回顾:
《TCP/IP详解卷1:协议》第3章 IP:网际协议(1)-读书笔记
《TCP/IP详解卷1:协议》第3章 IP:网际协议(2)-读书笔记
《TCP/IP详解卷1:协议》第4章 ARP:地址解析协议-读书笔记
《TCP/IP详解卷1:协议》第5章 RARP:逆地址解析协议-读书笔记
《TCP/IP详解卷1:协议》第6章 ICMP:Internet控制报文协议-读书笔记
《TCP/IP详解卷1:协议》第11章 UDP:用户数据报协议-读书笔记
《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(1)-读书笔记
《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(2)-读书笔记
《TCP/IP详解卷1:协议》第19章 TCP的交互数据流-读书笔记
3、连接建立的超时
有很多情况导致无法建立连接。一种情况是服务器主机没有处于正常状态。
4、最大报文段长度
最大报文段长度(MSS)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。
当建立一个连接时,每一方都有用于通告它期望接收的MSS选项(MSS选项只能出现在SYN报文段中)。如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节IP数据报)。
注意:
(1)一般说来,如果没有分段发生,MSS越大越好。报文段越大允许每个报文段传送的数据就越多,相对IP和TCP首部有更高的网络利用率。
(2)当TCP发送一个SYN时,或者是因为一个本地应用进程想发起一个连接,或者是因为另一端的主机收到了一个连接请求,它能将MSS值设置为外出接口上的MTU长度减去固定的IP首部和TCP首部长度。
(3)如果目的IP地址为“非本地的(non-local)”,MSS通常的默认值为536。
说明:区分地址是本地还是非本地的方法是:如果目的IP地址的网络号与子网号都与本机相同,则是本地的;如果目的IP地址的网络号与本机相同而子网号不同,则可能是本地的,也可能是非本地的。
(4)MSS使得主机限制另一端发送数据报的长度。加上主机也能控制它发送数据报的长度,这使得以较小MTU连接到一个网络上的主机避免分段。
下面举个书中的例子(比较懒,没有搭建环境)
主机sun向slip发起一个TCP连接,利用tcpdump命令来观察报文段:
说明:
(1)sun发送的报文段不能超过256字节的数据,因为slip已经告知它的MSS值为256。(上图第二个红框)
(2)slip知道它外出接口的MTU长度为296,所以即使sun已经告诉它的MSS为1460(上图第一个红框),但为避免将数据分段,它不会发送超过256字节数据的报文段。
(3)如果两端主机都连接到以太网上,都采用536的MSS,但中间网络采用296的MTU,同样会出现分段。
5、TCP的半关闭
TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力,即半关闭。
注意:很少有应用程序使用它,如果想要使用这个功能,需要编程接口提供一个方式来说明。
下面给出一个例子:
意思是这样的:客户结束了发送数据(发送了FIN),服务器发送ACK表示确认后,仍然可以发送数据给客户(图中红框)。
6、TCP的状态变迁图
下面这张图我没有仔细研究,它应该包含了有关发起和终止TCP连接的所有规则。
(1)2MSL等待状态
TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。
注意:MSL是个有限的时间,我们知道TCP报文段以IP数据报在网络中传输,IP数据报是由TTL字段限制其生存时间的。RFC 793指出MSL为2分钟。实现中的常用值是30秒,1分钟,或2分钟。
对于给定的MSL值,原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。
说明:
1)客户执行主动关闭并进入TIME_WAIT是正常的。服务器通常执行被动关闭,不会进入TIME_WAIT状态。
2)TCP连接在2MSL等待期间,这个连接的socket(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。
(2)平静时间的概念
如果处于2MSL等待端口的主机出现故障,它会在MSL秒内重新启动,并立即使用故障前处于2MSL的socket来建立一个新的连接。在故障前从这个连接发出而迟到的报文段会被错误地当作属于重启后新连接的报文段。
为了防止这种情况,RFC 793指出TCP在重启动后的MSL秒内不能建立任何连接,称为平静时间(quiet time)。
(3)FIN_WAIT_2状态
如上面的图所示:FIN_WAIT_2状态时,客户已经发出了FIN,另一端也已对它进行确认。
除非客户设置了半关闭,否则将等待另一端的应用层意识到它已收到一个文件结束符说明,并向我们发一个FIN 来关闭连接。只有这样,我们这端才会从FIN_WAIT_2状态进入TIME_WAIT状态。
7、复位报文段
TCP首部中的RST比特是用于“复位”的,一般无论何时一个报文段发往“基准连接”出现错误,TCP都会发出一个复位报文段。
说明:“基准连接”是指由目的IP地址和端口号以及源IP地址和端口号指明的连接。
(1)到不存在的端口的连接请求
产生复位的一种常见情况是当连接请求到达时,目的端口没有进程正在听。
注意:对于UDP,当一个数据报到达目的端口时,该端口没在使用,它将产生一个ICMP端口不可达的信息;对于TCP,则使用复位。
图中的意思是说:主机bsdi向svr4的20000端口发送SYN,然后svr4告诉bsdi一个复位连接的信息。
(2)异常终止一个连接
终止一个连接的正常方式是一方发送FIN。这也称为有序释放,因为在所有排队数据都已发送之后才发送FIN,正常情况下没有任何数据丢失。但也有可能发送一个复位报文段而不是FIN来中途释放一个连接。这也称为为异常释放。
异常终止一个连接对应用程序来说有两个优点:
1)丢弃任何待发数据并立即发送复位报文段;
2)RST的接收方会区分另一端执行的是异常关闭还是正常关闭。
特别注意:RST报文段不会导致另一端产生任何响应,另一端根本不进行确认。收到RST的一方将终止该连接,并通知应用层连接复位。
(3)检测半打开连接
如果一方已经关闭或异常终止连接而另一方却还不知道,将这样的TCP连接称为半打开的。
说明:
1)任何一端的主机异常都可能导致半打开连接。只要不在半打开连接上传输数据,仍处于连接状态的一方就不会检测到另一方已经出现异常。
2)半打开连接的另一个常见原因是当客户主机突然掉电而不是正常的结束客户应用程序后再关机。
8、同时打开
两个应用程序同时彼此执行主动打开的情况是可能的,尽管发生的可能性极小。每一方必须发送一个SYN,且这些SYN必须传递给对方。这需要每一方使用一个对方熟知的端口作为本地端口,称为同时打开。
TCP对于同时打开仅建立一条连接而不是两条连接。当出现同时打开时:
两端几乎同时发送SYN,并进入SYN_SENT状态。当每一端收到SYN时,状态变为SYN_RCVD,同时它们都再发SYN并对收到的SYN进行确认。当双方都收到SYN及相应的ACK时,状态都变迁为ESTABLISHED。
注意:
(1)一个同时打开的连接需要交换4个报文段,比正常的三次握手多一个。
(2)对于同时打开的连接,我们没有将任何一端称为客户或服务器,因为每一端既是客户又是服务器。
9、同时关闭
双方都执行主动关闭也是可能的,TCP也允许同时关闭。
同时关闭过程为:
(1)当应用层发出关闭命令时,两端均从ESTABLISHED变为FIN_WAIT_1。这将导致双方各发送一个FIN,两个FIN经过网络传送后分别到达另一端。
(2)收到FIN后,状态由FIN_WAIT_1变为CLOSING,并发送最后的ACK。
(3)当收到最后的ACK时,状态变化为TIME_WAIT。
注意:同时关闭和正常关闭报文段交换数目相同。
10、TCP选项
TCP首部可以包含选项部分。
选项说明:
(1)每个选项的开始是1字节kind字段,说明选项的类型。
(2)kind字段为0和1的选项仅占1个字节。其他选项在kind字节后还有len字节,它说明的长度是指总长度,包括kind字节和len字节。
(3)设置无操作选项的原因在于允许发方填充字段为4字节的倍数。
11、TCP 服务器的设计
大多数TCP服务器进程是并发的。当一个新的连接请求到达服务器时,服务器接受这个请求,并调用一个新进程来处理这个新的客户请求。
(1)TCP服务器端口号
当不同进程连接到服务器时,服务器端口号都是一样的。
(2)限定的本地IP地址
限制本地的IP地址后,不同链路的连接请求可能被TCP内核拒绝。
(3)限制远端IP地址
服务器必须不指明远端socket,而等待连接请求的到来,然后检查客户端的IP地址和端口号。
图18-22(这张图我还没有看懂)总结了TCP服务器进行连接时三种类型的地址绑定。在三种情况中,lport是服务器的熟知端口,local IP必须是一个本地接口的IP地址。
(4)呼入连接请求队列
一个并发服务器调用一个新的进程来处理每个客户请求,因此处于被动连接请求的服务器应该始终准备处理下一个呼入的连接请求。但仍有可能出现当服务器在创建一个新的进程时,或操作系统正忙于处理优先级更高的进程时,到达多个连接请求。
在伯克利的TCP实现中采用以下规则:
1)正等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已被TCP接受(即三次握手已经完成),但还没有被应用层所接受。
注意:TCP接受一个连接是将其放入这个队列,而应用层接受连接是将其从该队列中移出。
2)应用层将指明该队列的最大长度,这个值通常称为积压值(backlog)。它的取值范围是0~5之间的整数,包括0和5(大多数的应用程序都将这个值指明为5)。
3)当一个连接请求(SYN)到达时,TCP使用一个算法,根据当前连接队列中的连接数来确定是否接收这个连接。
4)如果对于新的连接请求,该TCP监听的端点的连接队列中还有空间,TCP模块将对SYN进行确认并完成连接的建立。
注意:
(i)应用层只有在三次握手中的第三个报文段收到后才会知道这个新连接。
(ii)当客户进程主动打开成功但服务器的应用层还不知道这个新的连接时,它可能会认为服务器进程已经准备好接收数据了。如果这样,服务器的TCP仅将接收的数据放入缓冲队列。
5)如果对于新的连接请求,连接队列中已没有空间,TCP将不理会收到的SYN,也不发回任何报文段(即不发回RST)。如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,客户的主动打开最终将超时。
《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(2)-读书笔记的更多相关文章
- 【TCP/IP详解 卷一:协议】第二十一章 TCP的超时与重传
作为TCP的重头戏,本章节涉及了许多关于计算方面的内容,使用了大量的例子来指明一些观点. 我使用的理解方法是:通过别人的博客,以及实例结合进行理解,不然会很吃力. 21.1 引言 reliable T ...
- 【TCP/IP详解 卷一:协议】第十七章 TCP:传输控制协议
本章作为TCP的入门章节,简单的概述了一些TCP的知识,和TCP数据报的首部格式. TCP 最重要的特性:reliable. 17.1 引言 本章介绍的是 TCP为应用层提供的服务. 17.2 TCP ...
- 【TCP/IP详解 卷一:协议】第二十三章 TCP的保活定时器
本章介绍保活定时器. 在 TCP 的三握四挥 章节中,我们介绍了 处在 TIME_WAIT 的 2MSL定时器:在 TCP的超时与重传 章节中,我们介绍了 重传定时器:在上一章节中,我们介绍了 防止死 ...
- 《TCP/IP详解 卷1:协议》读书笔记
第一章 概述 协议栈 应用层 HTTP,FTP 运输层 TCP, UDP 段(Segment) 网络层 IP, ICMP, IGMP 数据报(Datagram) 链路层 帧(Frame) 物理 ...
- tcp/ip详解 卷1 -- 协议概述
第一章 概述 分层 TCP/IP 通常被认为是一个四层协议系统. 每一层负责不同的功能. 链路层, 也成为数据链路层或者网络接口层. 通常包括 操作系统中的设备驱动程序和计算机中对应的网络接口卡. 主 ...
- 【TCP/IP详解 卷一:协议】第十一章 UDP 用户数据报协议
11.1 引言 UDP 是一个简单的 面向数据报 的运输层协议:进程的每个 输出操作 都正好产生一个 UDP数据报,并且组装成一份待发送的IP数据报. 这与 TCP 不一样,它是 面向流字符 的协议, ...
- 【TCP/IP详解 卷一:协议】第六章:DHCP 和自动配置
简介 为了使用 TCP/IP 协议族,每台主机or路由器都需要一定的配置信息: IP地址 子网掩码 广播地址 路由或转发表 DNS 协议配置方法: 手动 通过使用网络服务来获得 使用一些算法来自动确定 ...
- 【TCP/IP详解 卷一:协议】第十八章 TCP连接 的建立与终止 (2)其余内容
18.5 TCP的半关闭 牢记 TCP 是 全双工 的. 半关闭:TCP提供了连接的一端 在结束了它的发送后 还能接收来自另外一端数据的能力.但是只有很少的应用程序利用它. 为了实现这个特性,编程接口 ...
- 【TCP/IP详解 卷一:协议】第四章 ARP:地址解析协议 以及其他部分的一些知识
4.1 引言 数据链路 如以太网(Ethernet) 或者 令牌环网 都有自己的寻址机制(一般为 48 bit 的地址). 一个网络(数据链路层) 可以同时被多个不同的网络使用.比如,一组使用TCP/ ...
- 【TCP/IP详解 卷一:协议】第9章 IP选路
推荐链接:网络地址与主机地址 9.1 引言 路由选择程序(daemon),通常这是一个用户进程.在大多数的Unix系统中,大多数的路由选择程序都是路由程序和网关程序. 路由表经常被IP访问,但是它被路 ...
随机推荐
- openresty(nginx)、lua、drizzle调研
一.概述: 1.研究目标:nginx中使用lua脚本,及nginx直接访问mysql,redis 2.需要安装的内容: openresty,mysql,redis 3.OpenResty (也称为 n ...
- 构建多模块的Maven项目
在Eclipse下创建一个maven项目,该项目有多个模块组成. 1.创建父项目 File->New->Project->Maven->Maven Project(图一) ...
- html之大白
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 递归:codevs 1251 括号
codevs 1251 括号 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 计算乘法时,我们可以添加括号,来改变相乘的顺 ...
- Ajax读取文件时出现的缓存问题
对于Ajax缓存问题时,由于浏览器的版本问题,有时候当服务器端已更改文件中的内容,而客户端并得不到更新后的文件,而是延续之前的文件内容,解决办法是:在读取的文件内容后加一串的地址:JSON的格式为[{ ...
- java 为啥变量名前要加个m?
用m_开头表示类的成员变量,member的意思如果是全局变量,则由g_开头还有常量c_开头 静态变量s_开头
- 用SqlParameter 给SQL传递参数
1.数据访问层 using的用法: 01.可以using System;导命名控空间 02.using 的语法结构 using(变量类型 变量名 =new 变量类型()) { } 案例: 03.us ...
- 大话redis/memcache缓存
通常情况下,随着业务量增加,对后端数据库的访问压力也会随之加大.当数据库访问压力渐渐增大时,除了升级数据库配置提高数据库本身的抗压能力外,我们也可以采用在应用服务器与数据库服务器之间架设数据库缓存服务 ...
- Java中是否可以继承String类,为什么
Java中,是否可以继承String类?为什么? 答案: 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变. public final class ...
- Android应用性能优化之使用SparseArray替代HashMap
HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果.最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performanc ...