TCP/IP 协议学习(基础&握手与挥手详解)

导言

首先,不了解不知道,TCP/IP这个经典的协议,比想象中要复杂许多,细究下去才知道,一本讲TCP/IP协议的书的厚度可以与数据结构书媲美了。

TCP/IP协议,Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。

通俗来说,TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址 来源:百度百科

现在的网络系统是分层的,理论上有OSI模型,工业界有TCP/IP协议簇。其对比如下:

《TCP/IP 协议学习(基础&握手与挥手详解)》

可以看出对于TCP/IP协议来说,最主要的是这四个层:
链接层,网络层,传输层和应用层。

但首先,我们需要知道TCP在网络OSI的七层模型中的第四层——Transport层,IP在第三层——Network层,ARP在第二层——Data Link层,在第二层上的数据,我们叫Frame,在第三层上的数据叫Packet,第四层的数据叫Segment。

层与协议

  • Physical Layer
    用光缆、电缆、双绞线、无线电波等方式,将电脑互联。
  • Data Link Layer

    • 规定电信号分组的方式,以太网协议占据主导地位。
    • 以太网规定,一组电信号构成一个数据包,叫做”帧”(Frame)。每一帧分成两个部分:标头(Head)和数据(Data)。
    • 标头中包含了发送者和接受者的信息,这就用到了 MAC 地址。
    • 通过广播得到网络中每个主机的 MAC 地址
  • Network Link Layer

    • 它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫做”网络地址”,简称”网址”。
    • 网络地址帮助我们确定计算机所在的子网络,MAC地址则将数据包送到该子网络中的目标网卡。因此,从逻辑上可以推断,必定是先处理网络地址,然后再处理MAC地址。
  • Transport Layer

    • UDP&TCP
    • UDP协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到。
      为了解决这个问题,提高网络可靠性,TCP协议就诞生了。这个协议非常 复杂,但可以近似认为,它就是有确认机制的UDP协议,每发出一个数据 包都要求确认。如果有一个数据包遗失,就收不到确认,发出方就知道有 必要重发这个数据包了。

协议

互联网的每一层,都定义了很多协议。这些协议的总称,就叫做”互联网协议”(Internet Protocol Suite)。它们是互联网的核心。

我们在这里主要讨论TCP/IP协议

以访问Google为例:

  • TCP协议
    TCP数据包需要设置端口,接收方(Google)的HTTP端口默认是80,发送方(本机)的端口是一个随机生成的1024-65535之间的整数,假定为51775。

TCP数据包的标头长度为20字节,加上嵌入HTTP的数据包,总长度变为4980字节。

  • IP协议
    然后,TCP数据包再嵌入IP数据包。IP数据包需要设置双方的IP地址,这是已知的,发送方是192.168.1.100(本机),接收方172.194.72.105(Google)。

IP数据包的标头长度为20字节,加上嵌入的TCP数据包,总长度变为5000字节。

  • 以太网协议
    最后,IP数据包嵌入以太网数据包。以太网数据包需要设置双方的MAC地址,发送方为本机的网卡MAC地址,接收方为网关192.168.1.1的MAC地址(通过ARP协议得到)。

以太网数据包的数据部分,最大长度为1500字节,而现在的IP数据包长度为5000字节。因此,IP数据包必须分割成四个包。因为每个包都有自己的IP标头(20字节),所以四个包的IP数据包的长度分别为1500、1500、1500、560。

  • 服务器端响应
    经过多个网关的转发,Google的服务器172.194.72.105,收到了这四个以太网数据包。

根据IP标头的序号,Google将四个包拼起来,取出完整的TCP数据包,然后读出里面的”HTTP请求”,接着做出”HTTP响应”,再用TCP协议发回来。
本机收到HTTP响应以后,就可以将网页显示出来,完成一次网络通信。

握手与挥手

握手?:即建立连接
挥手?:即断开连接

经典的TCP协议建立连接(3次握手)和断开连接(4次挥手)

TCP报文中的重点字段

  • 序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  • 确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  • 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义:

       (A)URG:紧急指针(urgent pointer)有效。
       (B)ACK:确认序号有效。
       (C)PSH:接收方应该尽快将这个报文交给应用层。
       (D)RST:重置连接。
       (E)SYN:发起一个新连接。
       (F)FIN:释放一个连接。

3次握手

《TCP/IP 协议学习(基础&握手与挥手详解)》

  • 第一次握手:
    Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  • 第二次握手:
    Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  • 第三次握手:
    Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

4次挥手

对于这个,刚听说时,也感觉很困惑,挥手,这里应该是放手(断开连接)的意思吧,握一次手,放一次手,所以不也应该是3次挥手嘛?且看细解:

所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。
在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:

《TCP/IP 协议学习(基础&握手与挥手详解)》

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

  • 第一次挥手:
    Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  • 第二次挥手:
    Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  • 第三次挥手:
    Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  • 第四次挥手:
    Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

同时发起主动关闭的情况:

《TCP/IP 协议学习(基础&握手与挥手详解)》

  • 第一次挥手&第二次挥手:
    Client和Server都发送一个FIN,分别初始化为不同值,用来关闭双向的数据传送,两者都进入了FIN_WAIT_1状态。
  • 第三次挥手:
    Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态;Client收到FIN后,发送一个ACK给Server,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Client进入CLOSE_WAIT状态
  • 第四次挥手:
    收到FIN后,进入TIME_WAIT状态,接着发送一个ACK给对方,确认序号为收到序号+1,两者进入CLOSED状态,完成四次挥手。

此时,就可以回答困扰自己的问题啦:

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。所以就会出现确认方Ack=发起方Req+1。

Reference

通俗易懂深入理解TCP协议(上):理论基础-网络编程/专项技术区 – 即时通讯开发者社区!
互联网协议入门(一) – 阮一峰的网络日志
理论经典:TCP协议的3次握手与4次挥手过程详解-网络编程/专项技术区 – 即时通讯开发者社区!

    原文作者:TCP
    原文地址: https://segmentfault.com/a/1190000011284748
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞