Skip to content

深入理解TCP协议

分段一: 交换机的出现

  • 最开始的时候,两台计算机通信,只要用一根网线将他们连接起来就可以了,如果是老式的设备,可能还需要调整一下网线的线序
  • 但是随着计算机的增多,这种连接方式已经不能满足需求了,而且成本也太高了,操作也麻烦,于是那时候可以把每个计算机的网线拧在一起,这样可以实现多台计算机之间相互通信,而拧在一起的这个线团,就是最早期的集线器
  • 但集线器的缺点也很明显,每次发送的消息都会发给所有人,另外如果多台计算机同时发送消息会造成干扰,导致数据紊乱,于是交换机就出现了
  • 交换机通过内部的mac地址表,来决定信息流向,接入交换机的设备都必须要有自己的mac地址,计算机的mac地址是设备出厂时就设定好了的,这是全球唯一的,可以理解为设备的UUID

分段二: 交换机的工作方式

  • 如果A计算机要发送消息给B计算机,它需要在报文里写上自己的mac地址和B计算机的mac地址,将他们一起发送给交换机,交换机会将A计算机的mac地址记下来,跟接口1绑定(假定A计算机连接的是交换机的接口1),但此时交换机不知道B计算机mac地址对应哪个接口,于是会把消息以及目标即B计算机的mac地址发送给所有人,这个做法叫做泛洪
  • 当连接交换机的其他计算机C、D、E......等计算机接收到消息后,发现目标mac地址和自己不匹配,于是就会丢弃这个消息
  • 而B计算机接收到消息后,发现自己的mac地址可以匹配上,于是发送消息回应,同样的,回应的消息也需要写上自己的mac地址和A计算机的mac地址,回应的消息经过交换机之后,交换机也会将B计算机的mac地址和接口2进行绑定(假定B计算机连接的是交换机的接口2),由于之前交换机已经将A计算机的mac地址和接口1进行了绑定,所以交换机知道A计算机的mac地址应该发送给哪个接口,于是不需要再次泛洪,而是会将消息直接投递到接口1,从而直接把消息发送给A计算机,这样就完成了交换机mac地址发现到通信的过程
  • 如果以后A计算机还要发送消息到B计算机,交换机就会直接将消息发送到接口2,而不需要再次泛洪,这就是交换机的原理,,然而mac地址是根据设备绑定的,如果设备更换了网卡,那么mac地址就会发生变化,之前沟通过的计算机就会无法通信,需要再次泛洪,即目标计算机也要跟着修改A计算机的mac地址,所以mac地址的通信方式,对于更换网卡的情况,不是很友好,这时候我们需要一个更抽象的地址,这个地址就是ip地址

分段三: ip地址的工作方式

  • 假如依旧是A计算机发消息给B计算机,但是这次不是mac地址了,而是ip地址传输数据
  • A计算机需要在报文上写好自己的ip地址和B计算机的ip地址,因为要经过交换机,所以mac地址也要加上,但A计算机此时并不知道B计算机的mac地址,于是目标的mac地址就写不知道,然后将他们一起发送给交换机,然后根据交换机的泛洪,把消息发送给所有人,并比对所有计算机的ip地址,如果ip地址不匹配,就会将消息丢弃,直到匹配到B计算机的IP地址,B计算机收到消息后,会将A计算机的IP地址和mac地址绑定起来,以备下次使用,随后会对A计算机进行回应,告诉A计算机自己的mac地址,A计算机接收到回应后,会将B计算机的ip地址和mac地址绑定起来,以备下次使用,有了mac地址,两台计算机就可以直接进行通信了
  • 这个由IP地址到获得mac地址的过程,就是ARP协议,而计算机里面mac地址跟IP地址绑定的数据表则是APRP记录表

分段四: 多网络的通信 - 子网掩码的由来

  • 由于交换机泛洪特性,我们可以透过交换机直接将不同的网络联合起来,但是网络规模庞大之后,这样的联网方式并不合理,由于交换机会把每个经过的mac地址都保存起来,如果联网设备数量巨大,那么交换机的mac地址表将会无法容纳,另外交换机的全网泛洪也会导致效率问题(网络拥堵),于是我们希望将网络隔离开来,将网络分成不同的网段,交换机只用来传输同一网段的消息,于是有了子网掩码的概念
  • 子网掩码简单理解就是告诉计算机,子网的ID是IP的前面多少位数,简单理解,子网掩码前三段有值,那么子网IP就是IP的前三段,举例说明:
    • 子网掩码: 255.255.255.0 => 前三段有值
    • ip地址: 192.168.1.5 => 子网ID: 192.168.1.0
    • ip地址: 192.168.2.5 => 子网ID: 192.168.2.0
  • 这样我们就可以通过比对IP和子网ID,来确定是否属于同一个子网(网段),从而决定是否需要通过交换机进行通信,但这只是粗泛的理解,实际上子网掩码的规则要复杂的多,实际计算需要将IP和子网掩码转换成二进制进行计算,这样颗粒度更高,但原理是一样的,同样是按照子网掩码确定截取IP前多少位来作为子网ID,这里就不展开了
  • 这样计算机就可以知道目的IP是属于当前网段还是外网,如果是当前网段,则直接通过交换机通信,如果发送消息到外网,将交给专门的设备帮忙转发,这个设备就是路由器

分段五: 路由器的工作方式

  • 如果计算机A要发送消息给计算机C,并且通过子网掩码计算得知计算机C的IP地址不在当前子网,即当前IP为外网,那么就会将消息发送给路由器
  • 而计算机A之所以知道是哪台服务器,是因为计算器A的网关配置的是路由器的IP地址
  • 网关顾名思义就是各个子网的关口、出口,非内网的消息都经过网关出去
  • 路由器接受到消息后,怎么知道下一步要将消息给谁呢,是因为路由表,路由表可以配置网段和下一跳,它们用来决定各网段的消息下一步应该交给哪一个路由器设备,于是路由器就通过这种接力的方式将消息发送给目标计算机C
  • 路由表是手动配置的,当路由设备多起来之后,靠人工维护不太现实,于是有了自动互助学习、自动管理路由表的RIP、OSPF等动态路由协议
  • 当网络规模继续扩大之后,OSPF等协议也显得力不从心,于是有了BGP等协议,BGP协议是一种更高级的动态路由协议,可以自动管理路由表,并且可以自动更新路由表,但原理都是一样的,就是通过路由表来决定消息的下一步走向
  • 交换机、路由器各协议及IP协议的作用下,使用者可以不用关系复杂的网络环境,计算机通信就像单根网线直连一样,只需要关注自己的网络环境,通过配置网关,就可以实现跨网络通信,而不用关心消息的传输过程,但此时还有问题,例如IP协议只负责发消息投递到计算机,但我们的计算机是多应用的,比如浏览器、微信、QQ等,那么消息应该交给哪个应用呢,这就需要端口的概念了

分段六: 端口 - UDP协议

  • 不同的应用,我们使用不同的端口,发送报文时,除了前面的mac地址、IP地址外,还要加上源端口和目的端口,这样计算机接收到消息后,就可以根据端口来决定将消息交给哪个应用,从而实现多应用同时通信,而不用担心消息混乱的问题
  • 这种带端口的消息发送方式,其实就是UDP协议
  • UDP简单粗暴,但还是存在很多问题,例如消息丢失、消息重复、消息顺序混乱等,所以我们需要设计一个稳定可靠的协议,于是TCP协议就出现了

分段七: TCP协议 => 传输控制协议

  • 首先,网络是不稳定的,我们发送的消息很有可以能会在途中丢失,所以需要设置重试机制,当消息发送失败之后重新发送(假设为计算机A),为了判断是否发送成功,还需要在接收方(假设为计算机C)接收到消息之后,必须发送确认消息给发送方(计算机A),这样计算机A就知道消息已经成功发送,如果计算机A在规定时间内没有收到确认消息,那么就会重新发送,这就是TCP协议的可靠传输机制,这就保证了消息必达
  • 如果有大段的内容发送给计算机C,那么计算机C可能无法一次性接收完,很容易造成部分丢失,导致全部内容都要重新发送,于是TCP协议设计了分段机制,我们将数据分成多个包进行发送,如果分包发送失败,我们只需要重传分包数据即可,提高了传输效率
  • 此外,TCP协议还将每个包配上序号,这样计算机C就可以根据序号来重新组合消息,从而保证消息的顺序,这就是TCP协议的有序传输机制,并且接收方(计算机C)接收到消息,回复确认,也要带上序号,这样发送方(计算机A)就可以知道哪些消息已经成功发送,哪些消息需要重传
  • 注意:我们在前面的理解里,分包是一次性全部传过去的,但现实中,由于网络,客户端计算机处理能力等一系列原因,导致溢出的数据传输失败,于是需要控制每次传输分包的个数,于是有了滑动窗口,拥塞控制等技术,目的都是动态调整分包个数来优化传输流程,
  • 总结: 在TCP中,数据传输过程中会遇到两个主要的问题:丢包和延迟。为了解决这两个问题,TCP引入了慢启动和快重传机制
  • 不管是发送方的重传机制,还是接收方应答,数据整理机制,都需要双方分配计算资源来处理,为了提高计算效率,需要双方约定好一起开启,一起结束,而这个约定的开启和结束就叫做连接的建立和关闭,其实就是三次握手和四次挥手

分段八: TCP连接的建立和关闭

  • 建立连接: 三次握手
  • 发送方(计算机A)先传达一个连接意愿 => 在吗,来一把?
  • 接收方(计算机C)收到连接意愿后,回复一个连接确认,表示同意连接 => 在,来吗
  • 发送方(计算机A)收到连接确认后,再次发送一个连接确认,表示连接成功 => 来了,来了
  • 关闭连接: 四次挥手
  • 发送方(计算机A)先传达一个关闭意愿 => 要不退了吧
  • 接收方(计算机C)收到关闭意愿后,回复一个关闭确认,表示同意关闭 => 行,等我这把刷完
  • 接收方(计算机C)数据处理完毕,再向计算机A传达一个关闭意愿 => 刷完了,你可以退了
  • 发送方(计算机A)收到关闭确认后,再次发送一个关闭确认,表示关闭成功 => 你也退吧,下次别再打野了

分段九: NAT协议

  • UDP协议和TCP协议是应用层协议的根基,它们为应用层协议提供了传输保障,使得应用层协议可以专注于业务逻辑的实现,而不必担心消息的传输问题,所有的应用层协议都是在他们的基础上建立的
  • 随着网络的发展壮大,IP地址慢慢不够用了,于是有人想出了子网共用一个IP地址的方法
  • 假如计算机A和计算机B,同时发送消息给计算机C,但是它们没有公网IP,于是交给了网关路由器转发,路由器接收到后,建立端口映射表,记录着源端口、新端口,以及对应的内网IP,之后把报文中的来源IP改成公网IP,端口改成新端口,冒充子网计算机与外部通信,为计算机C响应消息时,网关路由器就可以根据端口映射表,把消息转发给对应的内网计算机(计算机A或计算机B),这就是NAT协议,NAT协议有效地解决了IP地址和IP地址匮乏问题
  • 这里加个补充,IP地址慢慢不够用了之后,又引入了IPv6协议,IPv6协议可以提供更多的IP地址,但是IPv6协议并不是直接替代IPv4协议,而是和IPv4协议共存,所以我们需要一个协议来将IPv4协议和IPv6协议进行转换,于是有了NAT协议,它可以将IPv4协议和IPv6协议进行转换,使得IPv4协议和IPv6协议可以互相通信
  • 总结: 将一个IP地址分成多个子网,每个子网使用不同的子网掩码,这样就可以实现多个子网共用一个IP地址,这就是NAT协议,它可以将多个子网共用一个IP地址,从而实现IP地址的复用