tcp/ip 协议介绍


一、tcp/ip 四层协议模型

在这里插入图片描述

1. 物理层

把电脑连起来,可以用光缆、电缆、双绞线、无线电波等方式,这就叫做“物理层”,把电脑连接起来的物理手段
它主要规定了网络的一些电气特性,负责传送 0 和 1 电信号

2. 数据链路层

单纯的 0 和 1 没有任何意义,必须规定解读方式:多少个电信号算一组?每个信号位有何意义?这就是“数据链路层”的功能,确定了 0 和 1 的分组方式

  • Ethernet:
    早期各公司都有自己的电信号分组方式,逐渐地“以太网”协议占据了主导地位。它规定一组电信号构成一个数据包叫做“帧”(Frame),分为Head和Data
    Head 包含数据包的一些说明项,比如发送者、接受者、数据类型等等,长度固定为 18 字节,Data 是数据包的具体内容,长度最短为 46 字节,最长为 1500 字节
    因此整个"帧"最短为 64 字节,最长为 1518 字节。如果数据很长,就必须分割成多个帧进行发送

  • MAC 地址:
    Head 发送者和接收者是如何标识呢?以太网规定,数据包必须是从一块网卡传送到另一块网卡
    通过网卡能够使不同的计算机之间连接,从而完成数据通信等功能。网卡地址叫做 MAC 地址,表示数据包的发送地址和接收地址

  • ARP 协议:
    以太网数据包必须知道接收方的 MAC 地址,然后才能发送,而一块网卡怎么知道另一块网卡的 MAC 地址呢
    ARP 地址解析协议,不是一个单纯的数据链路层协议,而是一个介于数据链路层和网络层之间的协议,通过IP地址查找MAC地址
    在这里插入图片描述
    在网络通讯时,源主机应用程序只知道目的主机的IP地址和端口号,却不知道目的主机的MAC地址,因此源主机在通讯前必须获得目的主机的MAC地址:
    1. 源主机发出ARP请求,询问“IP地址是172.20.1.2”的主机的MAC地址是多少’,并将这个请求广播到本地网段(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF表示广播)
    2. 目的主机接收到广播的ARP请求发现其中的IP地址与本机相符,发送一个ARP应答数据包给源主机,将自己的硬件MAC地址填写在应答包中
    3. 每台主机都维护一个ARP缓存表,表项过期时间一般20分钟,如果20分钟内没有再次使用这个表项,则该表项失效,下次还要发ARP请求来获取目的主机的硬件地址

  • 广播:有了 MAC 地址后,怎样才能把数据包送到接收方呢?以太网不是把数据包准确送到接收方,而是向本网络内所有计算机广播,每台计算机判断自己是否为接收方
    在这里插入图片描述上图中,1号计算机向 2 号计算机发送一个数据包,同一个子网络的 3 号、4号、5号计算机都会收到这个包
    它们读取这个包的Head,找到接收方的 MAC 地址,然后与自身的 MAC 地址相比较,如果两者相同就接受这个包,否则就丢弃这个包

  • MTU 最大传输单元:

    • 以太网和802.3对数据帧的长度都有一个限制,其最大值分别是1500和1492个字节,链路层的这个特性称作MTU。不同类型的网络大多数都有一个上限。如果IP层有一个数据要传,且数据的长度比链路层的 MTU还大,那么IP层就要进行分片(fragmentation),把数据报分成若干片
    • 把一份IP数据报进行分片以后,由到达目的端的IP层来进行重新组装,其目的是使分片和重新组装过程对传输层(TCP/UDP)是透明的。由于每一分片都是一个独立的包,当这些数据报的片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片
    • 尽管IP分片过程看起来透明的,但有一点让人不想使用它:即使只丢失一片数据也要重新传整个数据报,因为IP层本身没有超时重传机制
    • 使用UDP很容易导致IP分片,而TCP是不会造成IP分片的,因为一旦TCP数据过大超过了MSS,则在传输层会对TCP包进行分段,自然到了IP层的数据报肯定不会超过MTU,当然也就不用分片了。而对于UDP数据报,如果UDP组成的IP数据报长度超过了1500,那么IP数据报显然就要进行分片,因为UDP不能像TCP一样自己进行分段。总结:UDP不会分段由IP层来分,TCP会分段,不需要IP来分

3. 网络层

  • IP 报文格式
    在这里插入图片描述

  • 以太网协议依靠 MAC 地址发送数据,理论上单单依靠 MAC 地址,北京的网卡就可以找到深圳的网卡了,为何还需要网络层IP地址呢?
    以太网采用广播方式发送数据包,所有主机人手一包,不仅效率低,而且局限在发送者所在的子网络,如果两台计算机不在同一个子网络,广播是传不过去的,这种设计是合理的,否则互联网上每台计算机都会收到所有包,引起广播风暴。因此必须找到一种方法,能够区分哪些 MAC 地址属于同一个子网络,哪些不是,如果是同一个子网络,就采用广播方式发送,否则就采用路由方式发送。MAC 地址本身无法做到这一点,它只与厂商有关与所处网络无关,这就导致了“网络层”的诞生

  • IP地址:网络层的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。网络层的作用主要有两个,一个是为每一台计算机分配 IP 地址,另一个是确定哪些地址在同一个子网络。IP 地址分两个部分,前一部分代表网络号,后一部分代表主机号。怎样才能从 IP 地址,判断两台计算机是否属于同一个子网络呢?这就要用到“子网掩码”。将两个 IP 地址与子网掩码分别进行 AND 运算,然后比较结果是否相同,如果相同,就表明它们在同一个子网络中,否则就不是

  • DNS协议:DNS(域名解析协议)是一整套从域名映射到IP地址的系统。TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序,但是IP地址不方便记忆,于是人们发明了一种叫做主机名的东西,是一个字符串,并且使用hosts文件来描述主机和IP地址的关系。域名过程如下:
    - 域名服务器先查找自己缓存中的数据,如果没有就向上级域名服务器进行查找,以此类推
    - 最多回溯到根域名服务器,肯定能找到这个域名的IP地址

  • ping命令:向指定的IP地址发送一定长度的数据包,依照约定,若指定IP地址存在的话,会返回相同大小的数据包,若超时会被觉得指定的IP地址不存在
    ping使用的是ICMP协议,有些防火墙软件会屏蔽该协议,所以有时候ping的结果仅仅能作为參考,ping不通并不一定说明对方IP不存在

4. 传输层

  • tcp 报文格式 在这里插入图片描述TCP数据包每次能够传输的最大长度 = MTU(1500B) - IP头(20B)- TCP头(20B)= 1460B

    • 源端口号与目的端口号:标识了发送方与接收方的地址,IP地址和端口号合称为套接字
    • 序列号和确认号:可以理解成两个进程在收发数据的时候互相应答的信息。比如说:A进程从序列号1000开始给B进程发送数据,发送五个数据。那么在B收到数据回复的时候,这里A的确认序列号应该是从1006,如果不是1006,比如说是1003,那就意味着1004、1005数据包B没有收到,A将启动重发机制保证数据可靠性。序列号是进程发送消息的号码,而确认号是期望目的进程返回的号码,通过比对从而验证数据包是否到达
    • 报头长度:四位比特位表示的值4就是该TCP头部的长度。报头最短长度为20字节,也就是说这里的四位TCP报头默认为0101。TCP报头长度不可超过154=60个字节
    • 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
      • URG:紧急指针有效
      • ACK:确认序号有效
      • PSH:接收方应该尽快将这个报文交给应用层
      • RST:重置连接
      • SYN:发起一个新连接
      • FIN:释放一个连接
    • 窗口大小:标志着TCP缓冲区内部剩余空间的大小,起到一个流量控制的作用。如果窗口满了,那么这个时候是不允许数据接收的,到达的数据会被丢失
    • 校验和:这里的校验和由发送端填充,CRC校验。此处的校验和不仅仅校验TCP首部,还校验数据部分
    • 紧急指针:标识哪部分的数据为紧急数据

    MSS(Maxitum Segment Size)最大分段大小:

    • 为了达到最佳的传输效能TCP在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes),所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值
    • TCP是如何实现IP分段的呢?其实TCP无所谓分段,因为TCP报文大小已经被MSS限制了,由它形成的IP包的长度也就不会大于MTU,自然也就不用IP分片了。故采用TCP协议进行数据传输,是不会造成IP分片的。若数据过大,只会在传输层进行数据分段,到了IP层就不用分片
  • udp 报文格式
    在这里插入图片描述

  • 端口号
    有了 MAC 地址和 IP 地址,我们已经可以在互联网上任意两台主机上建立通信。接下来的问题是,同一台主机上有许多程序都需要用到网络,当一个数据包从互联网上发来的时候,怎么知道它是表示网页的内容,还是表示在线聊天的内容?因此我们还需要一个“端口”(port),表示数据包到底供哪个程序(进程)使用
    每个数据包都发到主机的特定端口,所以不同的程序就能取到自己所需要的数据

5. 应用层

应用程序收到“传输层”的数据,接下来就要进行解读。由于互联网是开放架构,数据来源五花八门,必须事先规定好解读格式。TCP 协议可以为各种各样的程序传递数据,比如 Email、WWW、FTP 等等。那么,必须有不同协议规定电子邮件、网页、FTP 数据的格式,这些应用程序协议就构成了“应用层”。这是最高的一层,直接面对用户。它的数据就放在 TCP 数据包的Data部分。因此,现在的以太网的数据包就变成下面这样

在这里插入图片描述

二、tcp 三次握手

1. 三次握手流程

通过三次握手建立可靠的双工连接,同步双方的初始序列号和TCP窗口信息,三次握手最主要目的是保证连接是双工的,可靠性更多的是通过后面重传机制来保证的:

  1. 第一次握手:Client 产生初始序列号 clientSequence, 置位 SYN ,然后发送 SYN 数据包,Client进入SYN_SENT状态。为了避免服务器被恶意攻击,SYN 的报文段不能携带数据,否则如果有人要恶意攻击服务器,每次都在第一次握手中的 SYN 报文中放入大量的数据,这会让服务器花费很多时间、内存空间来处理这些报文
  2. 第二次握手:Server将 clientSequence+1 作为确认号,置位 ACK,同时也产生初始序列号 serverSequence,置位 SYN,然后发送 SYN+ACK包,Server进入SYN_RCVD状态
  3. 第三次握手:Client将 serverSequence+1 作为确认号,置位ACK,然后发送ACK数据包,Client和Server进入ESTABLISHED状态,ACK报文段可以携带数据,因为对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收发送能力是正常的了,所以可以携带数据
    在这里插入图片描述

2. 为何需要三次握手

为了保证双方都知道自己能和对方发送和接收数据,即保证全双工:

  1. 第一次握手证明:服务端知道自己能从客户端接收数据
  2. 第二次握手证明:客户端知道自己能从服务端接收数据,同时也证明了第一步自己能成功向服务端发送数据
  3. 第三次握手证明:服务端知道自己能向客户端发送数据

三、tcp 四次挥手

1. 四次挥手流程

  • 第一次挥手:Client产生序列号 clientSequence,置位 FIN,Client主动关闭发送功能,Client进入FIN_WAIT_1状态
  • 第二次挥手:Server将 clientSequence+1 作为确认号,置位 ACK,Server认可Client关闭发送功能,Server进入CLOSE_WAIT状态
  • 第三次挥手:Server产生序列号 serverSequence,置位 FIN,关闭Server到Client的数据发送,Server进入LAST_ACK状态
  • 第四次挥手:Client将 serverSequence+1 作为确认号,置位ACK,Client认可Server关闭发送功能,Client和Server进入CLOSED状态
    在这里插入图片描述

2. 为何握手需要三次,而挥手需要四次

在三次握手时,服务端可以把 ACK 和 SYN放在一个报文里来发送,而在四次挥手时,服务端发送的FIN与ACK是分开发送的
原因在于:FIN信号是由于用户态调用close才被动发送的,而ACK是由内核收到数据包后主动发送的,所以ACK报文和FIN报文在发送的时间上是分开的,不一定能同时发送。但是三次握手的时候发送ACK和SYN都是由内核直接完成的,所以可以同时发送
在这里插入图片描述

3. 半连接,半打开,半关闭

  • 半连接状态:
    发生在TCP三次握手过程中,客户端向服务器发起连接,服务器也进行了回应,但是客户端却不进行第3次握手
    此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在半连接队列,已经完成三次握手建立起连接的就会放在全连接队列
    服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行多次首次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除

    Syn攻击:
    就是攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认。服务端会给每个待完成的半连接都设一个定时器,如果超过时间还没有收到客户端的ACK消息,则重新发送一次SYN-ACK消息给客户端,直到重试超过一定次数时才会放弃。这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
    检测 SYN 攻击非常的方便,netstat -np | grep SYN_RECV, 当看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击
    防范SYN攻击主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等,但是不能完全防范syn攻击

  • 半打开状态:
    在TCP连接中,如果某一端异常关闭,则该连接处于半打开状态
    TCP设有一个保活计时器,如果客户端出现故障,服务器不能一直等下去。服务器每收到客户端请求后都会重新复位这个计时器,通常是设置为2小时,若2小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接

  • 半关闭状态:
    当一端发送 FIN 请求关闭,另一端只回应ACK,并没有继续发送 FIN(第三次挥手) ,则处于半关闭状态
    服务器:文件描述符并没有关闭并归还,就会导致一种资源的泄漏,可能到最后就没有可分配的文件描述符了,那么就会使一些客户端无法连接
    客户端:此时客户端可以接收服务器发送的数据,但是客户端已经不能再向服务器发送数据

4. 四次挥手中为什么 TIME_WAIT 状态后还需要再等 2MSL后才能返回到 CLOSED 状态

保证可靠地终止TCP连接。处于TIME_WAIT状态的发送端在发送ACK后,无法知道ACK是否已经到达接收端,于是开始等待。假如ACK没有到达接收端,接收端会为FIN超时重传 。如果发送端等待时间足够,又收到FIN消息,说明ACK没有到达服务端,于是再发送ACK,直到在足够的时间内没有收到FIN,说明ACK成功到达。这个等待时间至少是:服务端的timeout + FIN的传输时间,为了保证可靠,采用更加保守的等待时间2MSL。再等待2MSL时间,可以使本次连接所产生的数据从网络中消失,从而保证关闭连接后不会还有在网络中滞留的数据。如果没有TIME_WAIT,那么无论对端有没有收到ACK,本端都已经关掉连接变成 CLOSED 状态了,此时对端重发FIN,本端将不会回复ACK,而是回复RST,从而使对端报错
在这里插入图片描述

四、tcp 滑动窗口

在确认应答机制中,对每一个发送的数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差,尤其是数据往返时间较长的时候。那么我们可不可以一次发送多个数据段呢:滑动窗口
流量控制就是让发送方的发送速率不要太快,让接收方来得及接收。利用滑动窗口机制可以很方便的在TCP连接上实现对发送方的流量控制

1. 窗口类型

  • 接收窗口rwnd(recv window):接收端缓冲区大小。接收端将此窗口值放在 TCP 报文的首部中的窗口字段,传送给发送端
  • 拥塞窗口cwnd(congestion window):发送端缓冲区的大小
  • 发送窗口swnd(send window):发送窗口是一个时刻变化的值,随着ACK的到达会变大,随着发出新的数据包会变小。当然最大也只能到三次握手时对方通告的窗口大小。tcp_push在发送数据时,最终会使用tcp_snd_wnd_test方法来判断当前待发送的数据,其序号是否超出了发送滑动窗口的大小

2. 滑动窗口原理

在这里插入图片描述如图,假设窗口大小为4000,那么1001-5001之间的数据是可以一次性全部发送,并且不需要等待ACK响应的。当发送完这4000的数据后再等待ACK。等到ACK响应中确认收到1001-2000的数据时,滑动窗口右移,以此类推。滑动窗口内的是已经发送但还没有收到ACK的数据,左侧是已经收到了ACK的数据,右侧是未发送的数据

3. 滑动窗口发送数据包

在这里插入图片描述
这里1001-2000的数据报文丢失,此时发送端并不知道,继续发送滑动窗口内的报文。这时候接收到了三条重复的ACK响应(收到三条相同的ACK响应就触发快重传速机制),重传1001-2000的数据报文。接收端乱序重排后响应为下一条是6001的数据报文,也就是说在2001-6000的报文都接收到了,这段报文被放到了接收端的接收缓冲区中。那么此时滑动窗口继续移动,发送端继续发送

4. 滑动窗口接收数据包

在这里插入图片描述
接连三条的ACK响应都丢包,但是第四条ACK响应到达,此时并不会影响发送端的发送。因为ACK响应的下一条数据包是4001,这意味着接收端已接收到前面的所以报文数据。所以接收端ACK响应丢包其实对发送端发送的影响并不是那么大,后续的ACK能够证明之前的数据都接收到了

5. 快速重传为什么是3次相同的ACK

假如发送方发送“12345”,接收方接到的是“1235”,接收方接到5的那一瞬间,知道4有可能丢了,也有可能乱序了,至于是哪种情况,接收方无从知晓
如果连续收到两个相同ACK,极有可能是乱序问题,重排后接收端会发送新的ACK,如果连续收到三个相同ACK,那么很大概率是丢包了,这个值在实际过程中也不一定就是3,可能远大于3,只是一个经验值

五、拥塞控制

拥塞控制是考虑当前的网络环境,动态调整滑动窗口大小。没有发生拥塞,则窗口增大,有发生拥塞,则窗口减小。如此往复,最终应该接近与接收端的窗口大小
在开始发送信息时,由于不知道具体的网络环境,为避免大量信息造成的拥塞现象,此时的拥塞窗口以最小值进行数据发送,并设定门限值作为慢启动算法和拥塞避免算法的分割点。慢启动是指以最小的拥塞窗口按照指数形式递增,达到门限值后,以拥塞避免算法,即线性递增方式增大拥塞窗口。在上述过程中,无论窗口大小指数递增或者线性递增,当发生拥塞现象时,则门限值更新为当前窗口大小的一半,拥塞窗口大小变为最小值,重复上述递增过程

在这里插入图片描述

六、tcp 状态切换

  • 服务端
    在这里插入图片描述

  • 客户端
    在这里插入图片描述

  • 连接建立与关闭转换图
    在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值