《TCP-IP详解卷一》笔记
-
TCP/IP的分层
-
数据的分用(以太网数据上来之后具体传到哪个上次协议的过程)
链路层
-
以太网封装格
-
-
最大传输单元MTU 以太网 1500字节
IP网际协议(不可靠、无连接)
-
IP首部
ARP 地址解析协议(ARP为I P地址到对应的硬件地址之间提供动态映射)
-
通信双方为什么必须知道对方的硬件地址(网络接口的硬件地址)?
在链路层协议中的目的地址和源地址都是硬件地址,链路层是不认识IP地址的(链路层为什么不能设计成认识IP地址的呢?因为他要适应不同的网络层协议,比如既要适应TCP/IP协议,也要适应某种PC网络软件)
-
ARP和RARP
【ARP协议】 32位Internet地址 ------> 48位以太网地址 【RARP协议】
-
ARP如何获取某一IP地址对应的硬件地址
ARP发送广播以太网数据帧,“你们谁是这个IP地址的拥有者呀?请回复!” 电缆上的所有以太网接口都要接收广播的数据帧。目的主机的A R P层收到这份广播报文后,识别出这是发送端在寻问它的 IP地址,于是发送一个ARP应答。这个ARP应答包含I P地址及对应的硬件地址。
-
每次网络层发送数据,ARP都要广播获取对方的硬件地址吗?
不是的,ARP有一个告诉缓存,arp -a 命令可查。
RARP 逆地址解析协议
-
逆地址解析协议有什么用
具有本地磁盘的系统引导时,从磁盘上读取配置文件中的相应的IP地址就可以了,但是无盘系统的引导则需要RARP协议,发送一份RARP请求(广播),以求某主机响应IP地址
ICMP: Internet控制报文协议(用于传递差错报文及其他需要注意的信息)
-
注意并不是ICMP请求才会有ICMP应答。ICMP是用来传递差错报文的,即使没有ICMP请求,如果网络传输中出现了错误,也会有ICMP应答报文。
PING 程序
-
该程序发送ICMP回显请求,并等待ICMP回显应答
-
Ping source code https://www.geeksforgeeks.org/ping-in-c/
TRACEROUTE 程序
-
traceroute实现的原理大致是怎样的?
start -> A ->B ->C -> Des
start是traceroute所在的服务器,Des是目的服务器,他们间隔A,B,C三个路由器。traceroute先发送一分TTL为1的IP数据包(目的地址是Des),A接受到后将TTL减1,由于A并不是目的地址且TTL已经变为0,所以A回复start ICMP差错报文;start再发送TTL为2的IP数据包,同理可知start再次受到了B的ICMP超时报文;C同理;start发送的IP数据包终于到达了Des,Des此时不再回复ICMP超时报文,traceroute程序发送的其实是UDP数据包给Des,端口大于30000,这个端口不可能被使用,于是Des给start回复端口不可达报文,start就知道目的地址到了,这一路上经过的站点也都知道了。
-
traceroute source code https://github.com/openbsd/src/blob/master/usr.sbin/traceroute/traceroute.c
IP 选路
-
选路是IP最重要的功能之一。本机的数据报本机一定会选路往下传,但是别的机器产生的数据包,必须把机器配成路由器,否则数据报的目的地址不是本机就被丢弃了。
-
-
netstat -rn 打印路由表
U: 该路由可以使用
G: 该路由是一个网关,它可以区分直接路由和间接路由
H: 该路由是一个主机,目的地址是一个完整的主机地址,没有该标志说明目的地址是一个网络地址
-
ICMP重定向差错报文可以优化路由
UDP:用户数据报协议
-
UDP是面向数据包的(而TCP是面向流字符的)。面向数据报与面向流字符到底是什么区别呢?
简而言之就是UDP在传输数据时是以数据报为单位的,不会进行拆分。而TCP由于有缓冲区这个东西的存在,它会对数据进行拆分,也可能会合并。见https://blog.****.net/****_kou/article/details/82083661
域名系统
-
域名系统是一种用于TCP/IP应用程序的分布式(Internet上的单个站点不能拥有所有信息)数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息。
TCP连接的建立与终止
-
TCP是面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。
-
tcpdump对tcp首部中部分比特的字符表示
-
三次握手及四次挥手
-
TCP连接是全双工,即数据在两个方向上能同时传送
-
收到一个FIN只意味着这一个方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。(半关闭)
-
TCP连接建立的超时时间:75s
-
最大报文段长度MSS,是在TCP传往另一段的最大报文段的长度。建立连接时,会进行MSS的协商
-
TCP半关闭,比较少用。调用close则两端都关闭,调用shutdown可以实现半关闭
-
TCP正常连接建立和终止所对应的状态
其中的TIME_WAIT状态又成为2MSL(两倍的报文段最大生存时间)状态,至于为什么要让主动发起关闭的客户端的等待2MSL之后再变为CLOSE状态呢,主要有两方面的原因; 1. 防止客户端最后发出的ACK报文服务器没有收到,这时候服务器会重传FIN|+ACK, 由于客户端还处于TIME_WAIT因此可以收到,也就可以再次发送ACK。 2.使本链接产生的报文全部消失,这个静置的方式可以防止影响下一个人的使用。
TCP的交互数据流
-
交互数据流是与成块数据流相对应的,TCP对两种数据流的处理算法不同
-
经受时延的ACK(200ms才发出去的那些ACK,200ms在实际观测中不一定真的是200ms,因为内核计时会溢出)
tcp在接受到数据需要返ACK确认的时候,并不是立即发送的,而是最大等200ms,看有没有需要返回的数据一同发出去(又称数据捎带ACK)。也就是TCP想看ACK这趟返回的列车能不能捎带上一些其他的数据,节省点油钱。
TCP的成块数据流
-
停止等待协议和滑动窗口协议
停止等待协议: 数据发送的一方,发送完一个数据块后等到确认才发下一个。只有一些简单的协议如TFTP中。
滑动窗口协议: 不必等到确认就可以连续发送多个,可以加速数据的传输。
-
在TCP中,ACK是累积的,他们表示接受方已经正确收到了一直到确认序号减1的所有字节。
-
窗口更新(下去的报文传输速度不匹配,发的快但是接受的慢)
其中的报文8,是对前面4,5,6,7的确认,并且告诉接收方窗口已经变为0,因为应用程序没有来得及读走。
其中的报文9看起来像是一个ACK报文,其实它什么都没有确认,只是告诉发送方自己的窗口又变大了,因此被称为窗口更新。
-
滑动窗口
-
窗口大小
接收方提供的窗口大小通常可以由接受进程控制,这将影响TCP的性能
窗口和缓冲区并不是以个东西,简单来说,窗口是缓冲的一部分。关于两者的关系,参看博文《TCP缓存区与窗口的关系》缓冲区大小在c语言中使用函数setsockopt函数设置的
-
PUSH标志,这个动作用来发送方告知接受放将收到的全部数据提交给接受进程。接受程序看到了push标志,就要毫不犹豫赶紧把数据交给进程
-
对push标志到底是什么时候被置为1仍没有完全理解!
TCP的超时和重传
-
TCP管理4个不同的定时器
a. 重传定时器,收不到确认时重传 b. 坚持定时器,使窗口大小信息保持不断流动 c.保活定时器,检测空闲连接的另一端核实崩溃或者重启 d. 2MSL定时器测量一个链接处于TIME_WAIT状态的时间
-
R <- aR + (1-a)M RTO = Rb (这个简单的计算方法已经被Jacobson更新)
这两个公式给出了超时重传时间RTO的计算方法。第一个公式 给出了往返时间的递推公式,一个a取值0.9,也就是90%来自前一个估计,10%取自新的测量。第二个公式给出了RTO和R的倍数关系,一般b取值2, 成为时延离散因子。
-
拥塞控制
TCP的坚持定时器
-
窗口更新的ACK报文是有可能丢失的(ACK的传输不可靠),万一丢了窗口岂不是一直处于关闭状态,发送方和接收方处于死锁干瞪眼的尴尬状态,为了解决潜在的问题,发送方会发送窗口探查报文。发送间隔使用了指数退避,时间间隔从一个开始值(算出来的),乘以2, 乘以4,乘以8,乘以16
TCP的保活定时器
-
保活并不是TCP规范的一部分,这是一个有争议的功能