《TCP/IP详解 卷1:协议》读书笔记。图片来自本书在即时通许网的电子版:http://www.52im.net/topic-tcpipvol1.html

第一章 概述

1.3 分层

分层

1.7 分用

分用

第二章 链路层

[图1.3](#1.3 分层)可看出,链路层三个目的:

1.为上层的IP模块发送和接收IP数据报

2、3. 为ARP和RARP发送请求和接收应答

2.6 PPP协议

这个东西还需要看看。

  • 环回地址就是常用的那个localhost,

    当目的地址是环回地址时,可以省略部分传输层、所有网络层的逻辑操作。但是大多数产品还是照样完成所有过程,只不过IP数据报离开网络层又返回给自己。

第三章 IP

3.1 引言

  • 不可靠 unreliable:不保证IP数据报成功到达目的地。

    发生错误,丢弃==》发送ICMP消息给信源

    任何要求的可靠性必须由上层提供

  • 无连接 connectionless:IP并不维护任何关于后续数据报的状态信息;每个数据报的处理是相互独立的。

    这也说明,IP数据报可以不按发送顺序接收。如果一信源向相同的信宿发送两个连续的数据报,先A后B。A和B独立进行路由选择,可能选择不同的路线,因此B可能先于A到达。

3.2 IP首部

  • 版本:4

  • 首部长度:和下面的选项(如今没啥用)有关。普通IP数据报(没有任何选项)字段值是5(20个字节)

    占4bit: 最大1111是15(60个字节)

  • TOS: 3bit的优先权字段(如今没用)

    4bit的子字段(只能有一个位置1)和1bit的未用位(必须置):

    因此这5bit只有4种情况:10000、01000、00100、00010

    这4种就是tcpdump的命令输出:0x10\0x08\0x04\0x02这四个十六进制数

    图3-2 服务类型字段推荐值

  • 总长:包括首部长度和数据部分长度。16bit IP数据报最长65535字节。但大多数链路层都会分片,而且,主机也要求不能接收超过576字节的数据报。

  • 生存时间 :TTL,它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位,当 TTL 为 0 时就丢弃数据报。

  • 协议 :指出携带的数据应该上交给哪个协议进行处理,例如 ICMP、TCP、UDP 等。

  • 首部检验和 :因为数据报每经过一个路由器,都要重新计算检验和,因此检验和不包含数据部分可以减少计算的工作量。

  • 标识 : 在数据报长度过长从而发生分片的情况下,相同数据报的不同分片具有相同的标识符。

  • 片偏移 : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。

3.3 路由选择

所有的IP路由选择只为数据报传输提供下一站路由器的IP地址。它假定下一站路由器比发送数据报的主机更接近目的,而且下一站路由器与该主机是直接相连的。

第四章 ARP

地址解析协议

从逻辑Internet地址到对应的物理硬件地址需要进行翻译。这就是ARP的功能。ARP本来是用于广播网络的,有许多主机或路由器连在同一个网络上。

ARP发送一份称作ARP请求的以太网数据帧给以太网上的每个主机。这个过程称作广播,如图4-2中的虚线所示。ARP请求数据帧中包含目的主机的IP地址(主机名为bsdi),其意思是“如果你是这个IP地址的拥有者,请回答你的硬件地址。”

图4-2 当用户输入命令"ftp主机名"时ARP的操作

ARP的功能是在32 bit的IP地址和采用不同网络技术的硬件地址之间提供动态映射。

4.3 ARP高速缓存

ARP高效运行的关键是由于每个主机上都有一个ARP高速缓存。这个高速缓存存放了最近Internet地址到硬件地址之间的映射记录。高速缓存中每一项的生存时间一般为20分钟,起始时间从被创建时开始算起。

我们可以用arp命令来检查ARP高速缓存。参数-a的意思是显示高速缓存中所有的内容。

4.6 ARP代理

如果ARP请求是从一个网络的主机发往另一个网络上的主机,那么连接这两个网络的路由器就可以回答该请求,这个过程称作委托ARP或ARP代理(Proxy ARP)。这样可以欺骗发起ARP请求的发送端,使它误以为路由器就是目的主机,而事实上目的主机是在路由器的“另一边”。路由器的功能相当于目的主机的代理,把分组从其他主机转发给它。

如果在主机gemini上执行arp命令,经过与主机sun通信以后,我们发现在同一个子网140.252.1上的netb和sun的IP地址映射的硬件地址是相同的。

ARP代理也称作混合ARP(promiscuousARP)或ARP出租(ARP hack)。这些名字来自于ARP代理的其他用途:通过两个物理网络之间的路由器可以互相隐藏物理网络。在这种情况下,两个物理网络可以使用相同的网络号,只要把中间的路由器设置成一个ARP代理,以响应一个网络到另一个网络主机的ARP请求。

4.9 小结

在大多数的TCP/IP实现中,ARP是一个基础协议,但是它的运行对于应用程序或系统管理员来说一般是透明的。ARP高速缓存在它的运行过程中非常关键,我们可以用arp命令对高速缓存进行检查和操作。高速缓存中的每一项内容都有一个定时器,根据它来删除不完整和完整的表项。arp命令可以显示和修改ARP高速缓存中的内容。

我们介绍了ARP的一般操作,同时也介绍了一些特殊的功能:委托ARP(当路由器对来自于另一个路由器接口的ARP请求进行应答时)和免费ARP(发送自己IP地址的ARP请求,一般发生在引导过程中)。

第五章 RARP

5.1 引言

具有本地磁盘的系统引导时,一般是从磁盘上的配置文件中读取IP地址。但是无盘机,如X终端或无盘工作站,则需要采用其他方法来获得IP地址。

网络上的每个系统都具有唯一的硬件地址,它是由网络接口生产厂家配置的。无盘系统的RARP实现过程是从接口卡上读取唯一的硬件地址,然后发送一份RARP请求(一帧在网络上广播的数据),请求某个主机响应该无盘系统的IP地址(在RARP应答中)。

在概念上这个过程是很简单的,但是实现起来常常比ARP要困难,其原因在本章后面介绍。RARP的正式规范是RFC 903[Finlayson et al.1984]。

第六章 ICMP

ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。

ICMP报文是在IP数据报内部被传输的,如图6-1所示。

第6章 ICMP:Internet控制报文协议_TCP/IP详解卷1 协议_即时通讯网(52im.net)

图6-1 ICMP封装在IP数据报内部
# 干货

抛开书籍看一下干货。

TCP/IP协议的作用:负责从应用传输数据到Internet

Application ——>TCP ——> IP ——> Internet

IP协议定义了地址功能,但IP不能保证数据包完整,所以依赖TCP协议

体系结构和主要协议

img

数据链路层:

处理数据在物理传输媒介上的传输

MTU的概念:

MTU是最大传输单元

ARP

地址解析协议
将IP地址转化为物理地址

RARP协议

逆地址解析协议
将物理地址转化为IP地址

这样就可以使数据在主机和数据链路层间传输了

网络层:

数据包的选路和转发

IP协议:

根据数据包的目的IP地址决定如何投递

IP传输通过路由器,使用分组转发算法去交付数据报(可以详细看一下分组转发,这里不作介绍)

为了更有效的转发IP数据报,这里使用了ICMP协议(国际控制报文协议)

ICMP协议:

检测网络连接

ICMP报文头部:

8位 区分报文类型 分为查询报文(查询网络信息)、差错报文(回应网络错误)

差错报文

(1)终点不可到达

(2)时间超过

(3)参数问题

(4)改变路由 (Redirect)

查询报文

(1)回送(Echo)请求和回答

(2)时间戳请求和回答

8位 细分不同报文
16位校验和 对整个报文进行循环冗余校验(CRC)检验报文是否损坏

应用:

  • ping:向目的主机发送ICMP Echo请求报文,会收到回答报文。以估算数据包RTT和丢包率

  • Traceroute 是 ICMP 的另一个应用,用来跟踪一个分组从源点到终点的路径。

    Traceroute 发送的 IP 数据报封装的是无法交付的 UDP 用户数据报,并由目的主机发送终点不可达差错报告报文。

至此,就能有效的让数据报在网络层和数据链路层间交付了

传输层:

只关心通信的起始端和目的端,不关心数据包的中转过程
这里有两个主要的协议,TCP协议和UDP协议,其实还有一个SCTP协议,但这里不做介绍(反正大家都没听过,就不讲了)

TCP协议:

为应用层提供可靠、面向连接、基于流的服务

UDP协议:

为应用层提供不可靠、无连接、基于数据报的服务

TCP协议使用了超时重传和数据确认的方式确认数据包被正确发送,所以TCP是可靠的

封装:

应用程序的数据,沿着协议栈从上往下的传递,每层数据都在上一层的基础上加上自己的头部信息。

应用数据——>加TCP/UDP头部信息——>加IP头部信息——>加帧首部和帧尾部

当自底向上传递的时候,就通过分用,各层协议以此处理帧中本层的头部数据,获取数据。

TCP

为什么要讲首部格式,为了了解首部每个部分负责的内容,从而更好的理解后面的知识 img

几个重点字段

序号:
占4字节。序号范围是 0 到 2的32次方-1 ,序号增加到 2的32次方-1 后,下一个序列号就回到了0。也就是说,序号使用mod 2的32次方 运算。TCP是面向字节流的,TCP连接中传送的字节流中的每一个字节都按顺序编号。首部中的序号就是指本报文段所发送数据的第一个字节的序号

确认号:

占4个字节,是期望收到对方下一个报文段的一个数据字节的序号

确认ACK:

当ACK=1时,确认号有效,当ACK=0时,确认号无效。当建立连接后所有传送的报文段都必须把ACK置1。 (区分开确认号和ACK)

同步SYN:

当SYN=1,ACK=0时,表明这是一个连接请求报文段。

终止FIN:

当FIN=1时。表明此报文的发送方的数据已经发送完毕,并要求释放运输连接。

三次握手

img

条件:服务器的传输控制模块TCB是一开始就被动创建好的(序列号后面会再讲)

1.客户端创建TCB,发起连接请求报文段,SYN置1,表示连接请求报文段 (不能携带数据,但会消耗一个序号)

2.当服务器接收到请求后,发起一个,SYN=1,ACK=1的连接接受报文段(不能携带数据,但会消耗一个序号)

3.当客户端收到接受报文后,需要在发送一条确认,此时ACK=1(能携带数据,如果不携带数据则不消耗序号)

四次挥手

img

数据连接结束后双方都可以释放连接:

1.A先发送连接释放报文段,终止控制位FIN置1(不能携带数据,但会消耗一个序号)

2.B收到连接释放报文段后,发出确认,ACK=1,确认号是序号+1。A收到B的确认后进入终止等待2状态,等待B发出的连接释放报文段。此时A向B的连接已经释放,TCP连接处于半关闭状态,也就是说A已经不向B发送数据,但B向A发送数据A任然接受。

3.当B已经没有要向A发送的数据,B就发送连接释放报文段,终止控制位FIN置1(不能携带数据,但会消耗一个序号)

4。A收到连接释放报文段后发送确认,ACK置1。但此时TCP连接并没有释放掉,A还需要进过时间等待计时器设置的时间2MSL后,TCP连接才完全释放。(这里又有两个问题,为什么需要这一步,为什么1,2不需要这一步)

首先,1,2不需要这一步是因为有超时重传机制,而4需要这一步也恰恰是因为超时重传机制。后面详细讲超时重传。

而第四点中,为了保证A发送的最后一个ACK报文段能够到达B,因为这个ACK报文可能丢失,那么B收不到A的确认,B会重新发送连接释放报文段,而A能在时间等待计时器设置的2MSL时间中收到请求。然后A重新开始第四步。

数据包在网络中是有生存时间的,超过这个时间还未到达目标主机就会被丢弃,并通知源主机。这称为报文最大生存时间(MSL,Maximum Segment Lifetime)。TIME_WAIT 要等待 2MSL 才会进入 CLOSED 状态。ACK 包到达服务器需要 MSL 时间,服务器重传 FIN 包也需要 MSL 时间,2MSL 是数据包往返的最大时间,如果 2MSL 后还未收到服务器重传的 FIN 包,就说明服务器已经收到了 ACK 包。

为什么不是两次

因为把三次握手改成两次将会发生死锁

例子:客户端B给服务器A发送了一个连接请求。服务器A收到了请求,并确认了请求。在假设是两次握手的情况下,在服务器A眼里TCP连接已经建立。但确认再传输中丢失,B并不觉得TCP连接建立。这种情况下B将忽略A的所有数据报,而A的数据报没有收到确认,会不断的超时重传,从而形成死锁。

为什么是四次?

为什么不是三次就别问了,跟三次握手为什么不是两次一样,得确认,不然死锁。

那为什么不是两次呢,因为TCP是全双工通信的,两次会到达半关闭状态,具体看上面的四次挥手过程。

超时重传机制

接下来讲一下超时重传、数据确认。至于为什么要确认借鉴为什么是三次握手而不是两次。

数据确认呢是这样的。

首先客户端发送一个数据报,序号为1,数据长度是1000。这里有一个超时计时器

那么服务器接收到后,会发送一个确认报文,确认号为1000+1。表示你下一个该发送的是1001。

那么如何处理发送丢包呢以及确认丢包呢

当客户端的超时计时器到期前,没有收到服务器的确认,无论是发送的包丢了,还是确认的包丢了,都会重新发送数据报。

重传超时时间(RTO, Retransmission Time Out)

这个值太大了会导致不必要的等待,太小会导致不必要的重传,理论上最好是网络 RTT 时间,但又受制于网络距离与瞬态时延变化,所以实际上使用自适应的动态算法(例如 Jacobson 算法和 Karn 算法等)来确定超时时间。

往返时间(RTT,Round-Trip Time)表示从发送端发送数据开始,到发送端收到来自接收端的 ACK 确认包(接收端收到数据后便立即确认),总共经历的时延。

重传次数

TCP数据包重传次数根据系统设置的不同而有所区别。有些系统,一个数据包只会被重传3次,如果重传3次后还未收到该数据包的 ACK 确认,就不再尝试重传。但有些要求很高的业务系统,会不断地重传丢失的数据包,以尽最大可能保证业务数据的正常交互。
最后需要说明的是,发送端只有在收到对方的 ACK 确认包后,才会清空输出缓冲区中的数据。

流量控制

为什么要进行流量控制,是为了让发送方的发送速率不要太快,让接收方来得及接收,减少丢失。

这里使用滑动窗口机制,例如在建立连接时,B告诉A接收窗口rwnd=400,那么发送方的窗口不能超过接收方给出的接收窗口数值。

 具体例子: 

 建立连接后,A发送序号=1,数据1~100 

 A发送序号=101,数据101~200 

 A发送序号=201,数据201~300(丢失) 

 B发送确认ACK=1,确认号=201,rwnd=300,表示要从201开始发送到500截至 

 A发送序号=301,数据301~400 

 A发送序号=401,数据401~500 

 201丢失,A发送序号=201,数据201~300 

 B发现太快了,发送确认ACK=1,确认号=501,rwnd=0,表示暂时不允许发送(零窗口) 

 当过了一段时间后,有了一些空间,发送ACK=1,确认号=501,rwnd=300 

 那么有一个问题了,当这个300的窗口报文丢失了怎么办呢? 

 这里有一个**持续计时器**,只要TCP一方收到对方的零窗口通知,就启动**持续计时器**,若持续时间到了,就给接收方发送一个,零窗口探测报文,若还是0,则重新定时,若不是0则打破死锁。 

拥塞避免

拥塞避免和流量控制有什么区别呢?

拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:1)慢开始、拥塞避免2)快重传、快恢复
流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。