《TCP/IP详解卷一》随笔

  关于这本书大概是第2.5遍看吧,第一次看了半本,啥概念没有,第二次模模糊糊看了一边,笔记写在OneNote,后来因为没有同步电脑重装就丢失了,第三次就是现在了。

  嗯,这篇真的真的是随笔了,很多地方被省略,例子也没有认真看,过了一下概念整理上来,概念部分也是很多地方没有写,因为很多都比较熟悉了,感觉不是那么重要,就没有写上来,所以这篇真的是笔记,不适合看。

  整理顺序没有按照书上的目录来,因为书中内容比较散乱,比如说在IP和UDP等章节说了ICMP之类的,我是把相关的东西整合到了一起,比如说关于ICMP的东西就全写道那一章这样子。

  一些高层协议的章节也被我跳过了,比如说FTP、SNMP之类的。

概述

  链路层。主要包括操作系统的设备驱动程序和计算机的网卡接口。
  网络层。处理网络中的分组传输。
  传输层。提供端到端的服务,本书主要涉及TCP和UDP。
  应用层。负责处理应用程序细节,程序处理数据后交给套接字。

  TCP/IP协议族是一组不同的协议组合的。TCP和IP只是其中两个协议。

  在链路层,主要有以太网协议、ARP、RARP三个协议。
  在网络层,主要有IP、ICMP、IGMP三个协议。
  在传输层,主要有TCP、UDP两个协议。

以太网协议

在这里插入图片描述
  一个以太网帧最小应该有14+46+4 = 64字节。大概是为了防止信号碰撞来着,64字节就能防止。
  头部6字节目的MAC,6字节源MAC,2字节类型,接下来是46~1500字节数据,最后跟4及字节CRC循环冗余码。

  类型字段:0x0800为IP协议,0x0806为ARP,0x8035为RARP。

  环回接口127.0.0.1。所有的发送的收到的数据包都会传递一份到该接口。

  SLIP和PPP被跳过。

ARP & RARP

在这里插入图片描述
  ARP和RARP都是用这个包结构。
  ARP通过IP地址询问MAC地址,RARP通过MAC地址询问IP地址。
  ARP表项超时时间一般是20分钟。
  ARP代理可以从一个网络到另一个网络发送ARP包。

  系统引导期间,通过ARP查询自己的IP地址。
  硬件类型字段:为1表示以太网地址。
  协议类型字段:为0x0800表示IP地址。
  硬件地址长度和协议长度长度字段:对于MAC和IP来说,分别是6和4。
  op字段:1和2分别是ARP请求/应答,3和4分别是RAPR请求/应答。

IP

在这里插入图片描述
  IP的校验和字段只覆盖其首部,不覆盖其数据。

  IP的路由选择
  路由表中每一项都包含:目的IP地址、下一跳路由的IP、标志(指明目的是网络地址还是主机地址)
  路由表搜索顺序:
    ①寻找能完全匹配(网络号主机号都匹配)目的地址的条目
    ②寻找目的网络号能匹配的条目
    ③发送到默认出口
    ④如果没有默认出口或者主机找不到,产生ICMP差错报文。

  IP分片。因为路径MTU的原因,IP可能需要分片,可能发生在主机也可能发生在路由器。
  分片过程:对于每份IP报,其表示字段都包含唯一一个值。该值被复制到每一个片中,并且每一片都设置分片位。片偏移字段指向相应的位置。如果设置了不分片位,则丢弃并产生ICMP差错报文。
  IP被分片后,每片包含一个IP首部,首部有足够信息让乱序到达的片重组。

  NAT代理:路由器一般提供代理服务。其行为是局域网内主机和外网通信,建立的TCP连接或者UDP数据报都会被路由器代理通信,细节上,局域网内connect外网时,路由器会以自己的IP地址去connect外网地址,然后实际上建立的TCP连接是路由器和外网地址的。
比如说局域网主机A(192.168.1.10 : 4567),路由器B(39.106.xx.xx),外网主机C(49.106.xx.xx : 8888),A connect C,实际上是路由器B选择一个端口(39.106.xx.xx : xxxx) connect C,B维护一个代理的列表,当收到C发来的数据,再转发给A。
  大概以前在一个远程服务器上调用过一次getpeeraddr函数,获取连接对端的地址,打印出来确实是路由器的地址。

  以下三个IP选项填写在IP报的那40字节里,不论是记录路由、时间戳还是源站选路都最多只能记录9个,每个记录4字节,需要另外的3字节来存储一些信息,所以只能是4*9+3。
    ①IP记录路由选项:记录路由在传递的过程中记录通过的路由器的IP地址。
    ②IP时间戳记录选项:时间戳是记录通过每个路由器时间,不过单独记录时间没什么意义,所以一般和记录路由一起,最多记录四对。
    ③宽松和严格的源站选路:源站选路是发送者通过填写选项字段,让报文通过指定的路由器。宽松即指定的路由器通过即可,不是必须一个挨着一个,严格即指定的路由器必须依次通过,中间不能有其他的路由器。

ICMP

在这里插入图片描述
  首先,ICMP被封装在IP数据包中传递。随后是上图中的结构,接下来在ICMP中始终包含<出错的IP首部以及接下来8字节>,这8字节是TCP或UDP中的端口字段。最后包含因为类型不同而不同的数据。
不会因为ICMP出错而产生另外的ICMP报文。

  ICMP路由发现
    路由器行为(路由器间通信见动态选路协议。)。
      路由器启动后,定期在所有广播多播接口发送通告报文,大概7-10分钟一次,一份通告有效时间是30分钟。通告内容为自己的所连通的路由器地址。
      当某个接口被关闭,通告报文内容有效时间被设为0。
      除了定期发送,还有监听并回复哪些那些来自主机的请求报文。
    主机行为
      主机引导期间每三秒发一份路由器请求报文,发三分,收到回复就停止发送。
      主机也监听来自相邻路由器的请求报文。这些主机会改变主机的默认路由器。

  ICMP源站抑制差错,当源端发送的数据到达目的端后,目的端来不及处理,可能会产生此报文来让源端降低发送速度,注意只是可能。

  ping和traceroute都通过ICMP的回显报文实现。traceroute通过端口不可达和报文超时来实现。另外还可通过稍微修改traceroute让其实现确定路径MTU的功能,即设置不分片位,不断尝试,直到不再收到ICMP的差错报文。

IGMP

  IGMM直接使用IP封装。
  IGMP在主机或路由器上由多播选路的守护程序提供服务。
  多播地址224.0.0.1是所有有多播能力的主机或路由器都会加入的组。称为所有主机组。
  多播服务对每个接口保持一个表,表示并记录该接口上至少还包含一个主机的多播组。
  IGMP的生存时间字段总是设为1,使其保持在局域网。

  IGMP的报告和查询
    当某个主机上某个进程加入一个组,主机发送一个IGMP报告。这个报告被发给该接口上所有主机。
    主机离开多播组时,不发送报告。
    多播的守护程序通过定时发送IGMP查询来查看哪些主机上的进程还在多播组。
    主机则通过IGMP报告相应多播守护程序的查询。

TCP

在这里插入图片描述
  TCP连接的建立与终止
    三次握手
      客户端首先发送SYN包来发起连接
      服务端收到客户端的SYN后,发送一个ACK+SYN包,ACK确认客户端的的SYN包,SYN则是服务端的连的握手包。
      最后客户端收到服务端的ACK+SYN后,向服务端发送一个ACK来确认服务端的SYN。
    服务端收到最后的ACK后,将该链接放入已连接队列,等待调用accept将其取出队列。

    四次挥手
      不论哪一端都可能先关闭,这里称为A、B端
      A首先发送一个FIN包(注意SYN不占序号,但是FIN会占一个序号),表示自己没有数据可发了。
      B端收到FIN后,向对方发送一个ACK来确认其FIN。
    接着B在发送完数据后,也向A发送一个FIN,表示自己也不会发送数据了。
      最后A收到B的FIN后,向B发送一个ACK,连接正式终止。
TCP连接队列。
      套接字有两个队列,一个是正在进行三次握手的连接队列,一个是已完成三次握手的已连接队列。

  半打开半关闭
    半打开半关闭状态有两种情况,一种是主动的,一种是被动的。
    主动的半打开半关闭是调用shutdown函数后,某个套接字 不收数据 或者 不发数据。
    被动是诸如断电断网等,TCP连接的一方因为某些原因消失,但是只要该连接的两方没有数据的流通,就不会发现一方消失(或许有心跳机制),只要有数据流通,这种情况下就可能收到ICMP差错或者RST复位。
    RST标志的主要作用就是可以跳过TIME_WAIT状态,关于TIME_WAIT状态见后。该行为可以通过so_linger套接字选项设置,详见unp第七章。

  同时打开同时关闭
    TCP同时向对方发起连接虽然少见,但还是可能出现的,三次握手变成四次,两端都像对方发送一个SYN握手包,接着又同时回复对方一个ACK包,连接建立。
    因为网络不通的原因,大多数实现,客户端连接时会会在75秒内尝试连接三次,如果依旧不成功就放弃。

  状态变迁图。FIN_WAIT_2和TIME_WAIT
在这里插入图片描述
    FIN_WAIT_2状态。该状态表示当前端发送了FIN并收到了对方的确认,正在等待对方的FIN,当对方的FIN到达,才会进入TIME_WAIT状态。
    TIME_WAIT状态。见unp第二章第一条。

  Nagle算法。为了减小网络流量存在,将碎片搬的数据积攒,到某个时刻一起发送以减少流量。

  滑动窗口
    换个角度就是套接字的发送缓冲区和接收缓冲区吧,大概有一次抓包的时候看到窗口大小是65535?以下全是瞎bb:
    对于发送缓冲区,滑动窗口覆盖着已发送但未收到对方ACK的数据、以及将要发送出去的数据,当收到ACK,窗口向右靠拢,新的要发送的数据被窗口覆盖,等待发送。
    对于接收缓冲区,滑动窗口覆盖着已接收的数据,当网络新的数据到达,数据依次写到队列右边,当应用层调用recv取出数据,滑动窗口右移。

  紧急数据。大概另一种说法是带外数据?见unp第二十四章。

  超时与重传 & 重新分组
    TCP对于每个连接都维护四个定时器
      ①重传定时器。当发送出去的数据在一定时间内未收到对方ACK,就会发生重传。重传是可能发生重新分租,即有新的数据需要发送,重新分组就是把丢失的数据和新的数据一起打包发送。
      ②坚持定时器。如果一个确认丢失,双方可能因为等待对方而终止,接收方等待数据(并且向对方通告了窗口大小为0),而此时发送方在等待接收方发来窗口大小的更新,坚持定时器是为了防止这种死锁而存在,发送方周期性向对方查询窗口是否增大。坚持定时器使用指数退避方式查询,但是查询时间上限不会超过60秒。窗口探查包含一个字节数据,虽然窗口大小被通告为0,但这一字节是被允许的。接收端返回的ACK不确认这一个字节,ACK的是先前接收的数据。
      糊涂窗口综合症:接收方通过的窗口很小,发送方也发送了很少量的数据。
      措施:接收方的窗口很小时直接不通告或者通告为0,直到窗口大小大于某个阙值。发送放则在:a.可以发送满长度报文段;b.可发送的数据至少是接收方通告窗口的一半;c.发送缓冲区全部数据能被发送且不希望接收ACK(发送方还有未被确认的数据);d.Nagle算法被关闭任一条件满足的情况下才发送。
      ③保活定时器。(心跳)
主要就是TCP连接双方的某一方可能因为断电 断网 或者其他原因,导致一方连接消失却没有任何回应,双方又长时间没有数据流通,也就无法通过ICMP差错发现连接丢失,然后导致已丢失连接长时间占用资源。心跳机制定期向对方发送数据并收到确认,来确认对方连接存在,如果一方连接丢失,通过心跳机制产生的ICMP差错发现,及时关闭已丢失连接
      ④2MSL定时器,TIME_WAIT状态。

  慢启动 & 拥塞避免算法 & 快速重传 & 快速恢复算法。
    拥塞控制窗口变量cwnd
    慢启动门限变量sstresh,初始值65535。
    慢启动是每次发送发送数据收到确认后,下一次发送的数据是当前的翻倍。单位是报文段(没明白报文段这个概念)
    拥塞避免是每次发送增加一个报文段大小。
    区别就是一个增长快一个增长慢。
    当cwnd <sstresh,使用慢启动算法,每次发送数据量都翻倍。
    当cwnd > sstresh,使用拥塞避免算法,每次发送数据量只增加一个报文段。
    当数据被ACK时,增加cwnd大小。一个报文段大小。
    当发生拥塞时,sstresh被设为cwnd的一半来试图避免拥塞。也就是说使用拥塞避免算法,当发生超时和重复的确认时即代表拥塞丢包。

  收到失序报文段时,TCP产生重复确认报文,该重复确认不等待立即发送出去,让发送端尽快重发,此为快速重传。接下来大概是发送端执行拥塞避免而不是慢启动。这个叫快速恢复,唉,抄书了,不明白具体是个啥。

  TCP的未来
    ①窗口扩大选项使最大的TCP窗口从65535增加到1千兆字节以上。时间戳选项允许多个报文段被精确计时,并且允许接收方提供序号回绕保护。序号回绕指高速度的数据传输下,TCP中的序号字段绕过42亿多后回到0开始,可能发生回绕前的包和回绕后的包序列号一样。
    ②为事务用的TCP扩张,允许CS的请求/应答序列只使用三个报文段完成。避免三次握手,缩短TIME_WAIT,方法是为每个主句高速缓存少量信息,这些信息曾建立过一个连接,在数据报文段中直接包含SYN和FIN标志。

UDP

在这里插入图片描述
  UDP长度字段包括其首部和数据。
  UDP的检验和大概要覆盖一个伪首部?包括源IP、目的IP、协议类型和UDP长度等字段。

广播和多播

  广播和多播仅应用于UDP。

  网卡查看由信道传送过来的帧,判断目的地址(MAC)地址是否匹配,或者是广播或者多播地址,才接收。

  关于广播地址,首先通过子网掩码和地址确定该子网范围,第一个地址是子网的网络地址,最后一个地址是子网的广播地址,对于255.255.255.255的广播包,路由器不会转发,仅在当前局域网内广播。

  多播的概念以及应用层sock的使用流程,见unp第二十一章。

DNS

  关于DNS具体就不写了。

  DNS主要用于使用IP查询域名,或者反过来,在Linux的API里应该是gethostbyname和gethostbyaddr。

  关于DNS使用TCP还是UDP,一般情况下的普通查询使用UDP,但是在传输很多数据时使用TCP,比如说一个DNS服务器从另一个DNS服务器拉取大量的条目,或者DNS服务器备份。

动态选路协议(路由器间通信)

  主要分为内部网关协议和外部网关协议
    内部网关协议主要是RIP(路由信息协议)和OSPF(开放最短路径优先)。
    外部网关协议主要是BGP(边界网关协议)。

  RIP。封装在UDP报中。
    启动一个路由守护程序时,先判断启动了哪些接口,然后在每个接口上发送一个请求报文,要求其他路由器发送完整路由表。
    接到响应时,更新路由表。
    接到其他路由器的请求时,就把完整路由表发给对方。
    每30秒定期把路由表发给周围路由器。

  OSPF。封装在IP报中。
    是一个链路状态协议,其距离向量表示路由器的跳数。
    路由器不与邻站交换信息,采用每个路由主动测试与邻站相连链路的状态,邻站则把这些信息在自治系统(暂时理解成局域网校园网之类的)传播出去,每个路由器接收这些状态信息,然后建立完整路由表。

  BGP。封装在TCP报中。
    两个运行BFP的系统间建立TCP连接,然后交换整个路由表,随后只要路由表变化,就发送更新信号。

TFTP简单文件传输协议

在这里插入图片描述

  TFTP使用UDP封装。
  TFTP是一个简单协议,适合只读存储器,主要用于无盘系统的引导,是一个停等协议。
TFTP没有差错检查,通过UDP校验和检错。
  开始工作时,TFTP客户与服务器交换信息,客户发送读或者写请求给服务器,在一个正常的无盘系统引导下,第一个是读请求。

BOOTP引导程序协议

  BOOTP使用UDP封装。为无盘系统引导提供了另一种方式。且通常和TFTP协同工作。
  BOOTP用于系统引导过程,所以只需要在只读存储器实现:BOOTP、TFTP、UDP、IP
  BOOTP相较于RARP,可以穿越路由器实现。
  BOOTP服务器一般使用67端口,客户端使用68端口,因为使用广播不太好。

                                      2020年10月28日20:38:45

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值