认识TCP,记住TCP链接的三次「握手」、四次「挥手」

最近在看『浏览器从输入网址到页面展示发生了什么』,然后过程中涉及到了建立TCP链接和断开TCP链接的过程,所以单独再补习一下TCP相关的计算机网络知识。

一、TCP是什么?

TCP 是一个面向连接的、可靠的、基于字节流的传输层通信协议。

  • 面向连接(connection-oriented):面向连接的协议要求正式发送数据之前需要通过「握手」建立一个逻辑连接,结束通信时也是通过有序的四次「挥手」来断开连接。
  • 无连接(connectionless):无连接的协议则不需要「握手」和「挥手」

TCP/IP协议族

TCP/IP 协议族不仅仅是 TCPIP 这两种协议,实际上TCP/IP 协议族指的是在 IP 协议通信过程中用到的协议的统称。

其中常见到的协议:

  • IP:因特网互联协议
  • FTP:文件传输协议
  • HTTP:超文本传输协议

分层模型

TCP/IP协议分为4层:应用层、传输层、网络层、网络接口层
OSI分为7层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

二、TCP头部详解

TCP固定头部20字节,IP固定头部20字节,TCP头部最长可以达到60字节。

  1. TCP端口号

    TCP的链接需要四个要素确定唯一链接:源IP,源端口号 + 目的IP,目的端口号

    TCP首部预留了2个16位作为端口号的存储,而IP地址由上一层IP协议负责传递。

  2. TCP序号和确认号

    • 32位序号seqTCP通信过程中某一个传输方向上的字节流的每个字节的序号,通过这个来确认发送的数据有序
    • 32位确认号ackTCP对上一次seq序号做出的确认号,用来响应TCP报文段,给收到的TCP报文段的序号seq加1。
  3. TCP标志位

    • SYN:同步标志位,用于建立会话连接,同步序列号
    • ACK:确认标志位,对已接收的数据包进行确认
    • FIN:完成标志位,表示我已经没有数据要发送了,即将关闭连接

三、TCP的三次握手

三次握手是指建立一个 TCP 连接时,需要客户端和服务器之间总共发送3个报文。

初始时客户端处于closed的状态,服务端处于listen状态。

  1. 第一次握手

    客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器确认。

  2. 第二次握手

    服务器端收到数据包后,由标志位SYN=1知道客户端请求建立链接,服务器端将TCP报文标志位SYNACK都置为1ack=J+1,随机产生一个序号值seq=K,并将该数据包发送给客户端以确认链接请求,服务端进入SYN_RCVD状态。

  3. 第三次握手

    客户端收到确认后,检查ack是否为J+1ACK是否为1,如果正确则将标志位ACK置为1ack=K+1,并将该数据包发送给服务器端,服务器检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

注:ackACK是不同的概念

  • ack (Acknowledge number),代表头部的确认号,是对上一个包的序号进行确认的号,ack=seq+1
  • ACK:是TCP的首部标志位,是用于标志TCP包是否对上一个包进行了确认操作,如果确认,则ACK为1。

为什么要三次握手?

谢希仁版《计算机网络》中的例子

  1. 假设client发出的第一个连接请求报文段并没有丢失,而是在某个网络节点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server
  2. 本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。
  3. 假设采用两次握手,只要server发出确认,新的连接就建立了。
  4. 但由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
  5. 而采用"三次握手"的办法可以防止上述现象发生。像刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

四、四次挥手关闭连接

TCP链接是全双工的,因此,每个方向都必须要单独进行关闭。

挥手请求可以是Client端发起,也可以是Server端发起的,我们假设是Client端发起。

  1. 第一次挥手

    Client端发送标志位FIN和序号seqServer端,此时Client进入FIN_WAIT_1状态,表示Client没有数据要发给Server端了,希望关闭连接。

  2. 第二次挥手

    Server端收到FIN后,回复标志位ACK和确认号ack给客户端,此时Client端进入FIN_WAIT_2状态,表示Server端已经收到Client端的关闭请求。

  3. 第三次挥手

    Server端发送标志位FINClient端,此时Client端进入LAST_ACK状态,表示服务端数据发送结束,可以关闭链接了。

  4. 第四次挥手

    Client端收到Server端发送的FIN后,回复标志位ACKServer端,此时Client端进入TIME_WAIT状态。Server端收到ACK后,就立即关闭连接了。Client端则等待2MSL的时间后,没有收到回复,则证明Server端已正常关闭,Client便也关闭连接。

相关推荐
lyj1689974 分钟前
vue-i18n+vscode+vue 多语言使用
前端·vue.js·vscode
一只小鱼儿吖32 分钟前
进程代理单窗口单IP技术:原理、应用与实现
网络·网络协议·tcp/ip
稳联技术33 分钟前
Ethernet IP与Profinet共舞:网关驱动绿色工业的智慧脉动
网络·网络协议·tcp/ip
计算机毕设定制辅导-无忧学长1 小时前
西门子 PLC 与 Modbus 集成:S7-1500 RTU/TCP 配置指南(一)
服务器·数据库·tcp/ip
小白变怪兽1 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头2 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
墨菲安全2 小时前
NPM组件 betsson 等窃取主机敏感信息
前端·npm·node.js·软件供应链安全·主机信息窃取·npm组件投毒
GISer_Jing2 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆2 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试
游戏开发爱好者83 小时前
iOS App首次启动请求异常调试:一次冷启动链路抓包与初始化流程修复
websocket·网络协议·tcp/ip·http·网络安全·https·udp