你会爱上我的(ಥ_ಥ) ——TCP详解
最后更新于
最后更新于
简单归纳
浏览器通过 DNS 域名解析到服务 IP(ping www.baidu.com)
客户端(浏览器)通过 TCP 协议建立到服务器的 TCP 连接(三次握手)
客户端(浏览器)向 web 服务器端(HTTP 服务器)发送 HTTP 协议包,请求服务器里的资源文档
服务器向客户端发送 HTTP 协议应答包
客户端和服务器断开(四次挥手),客户端开始解释处理 HTML 文档
为什么需要DNS解析域名为IP地址
网络通讯大部分是基于 TCP/IP,而TCP/IP 是基于IP地址的,所以我们在进行访问通讯只能识别IP地址,而不能解析域名,但是我们无法记住IP地址的网站,所以我们访问网站时,更多的是在浏览器输入url地址,就能看到所需要的页面,这就需要DNS服务器的计算自动把我们的域名翻译成相应的IP地址,然后调用IP地址展示对应的网页。
浏览器缓存
当用户访问一个域名地址的时候,客户端(浏览器)会先看看浏览器是否有缓存,如果有该域名对应的IP,则进行返回
系统缓存
当在浏览器缓存中没有查找到对应的IP,则会检查用户的系统Host文件,看看是否有与该域名对应的IP
路由器缓存
当在浏览器和系统Host文件中都没有查找到对应的IP,则会进入路由器缓存中进行检查
以上三步都是在客户端进行查询DNS缓存
ISP (互联网服务) DNS缓存
当用户在客户端没有查找到该域名对应的IP,则会进入 ISP DNS 缓存中进行查询,如果你用的是移动网络,则会进入移动网的DNS缓存服务器中进行查找
根域名服务器
当以上均未完成,则进入根服务器进行查询。全球仅有13台根域名服务器,1个主根域名服务器,其余12个为辅根域名服务器。根域名收到请求后会查看域名文件记录,若无则将其管辖范围内顶级域名(.com)服务器IP告诉本地DNS服务器
主域名服务器
主域名服务器接受到请求后查询自己的缓存,如果没有则进入下一级域名服务器进行查找,并重复该步骤直至找到正确记录
保存结果至缓存
本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时将该结果反馈给客户端,客户端通过这个IP与Web服务端建立连接。
面向连接的 TCP
可靠,过程复杂
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个 TCP 连接必须要经过三次”对话”才能建立起来。
面向非连接的 UDP 协议
不可靠,实时(视频,语音通话)
“面向非连接”就是在正式通信前不必与对方先建立连接,不管对方状态就直接发送。与手机短信非常相似:你在发短信时,只需要输入对方手机号就可以。 UDP(User Data Protocol,用户数据报协议)是与 TCP 相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接把数据包发送过去。
TCP 是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条”连接”。其实是客户端和服务器的内存里保存一份关于对方的信息,如ip地址
、端口号
等等。
简单描述
先客户端发送连接,请求报文
服务端连接后回复 ACK 报文,并为这次连接分配资源
客户端接收到 ACK 报文后也向服务端发送 ACK 报文,并分配资源
作用:为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。
详细描述三次握手
刚开始客户端处于 closed 的状态,服务端处于 listen 状态
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序号ISN(c)。此时客户端处于SYN_Send状态,等待服务器的确认。 第二次握手:服务器接收到客户端的 SYN 报文后,会对这个 SYN 报文段进行确认,并将自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(c),同时会把客户端的 ISN+1 作为ACK的值,表示自己已经收到了客户端的 SYN,此时服务器处于SYN_RCVD状态。 第三次握手:客户端收到 SYN 报文之后,回发送一个 ACK 报文,也是一样把服务器的 ISN+1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于ESTABLISHED状态。 服务器收到 ACK 报文后,也处于ESTABLISHED状态,此时,双方建立起了链接,完成 TCP 三次握手。
三次握手的目的
为了防止已失效的连接请求报文突然又传送到服务端,因而产生错误
为了解决”网络中存在延迟的重复分组”问题
指定自己的初始化序列号,为后面的可靠传送做准备
如果是 https 协议的话,三次握手这个过程,还会进行数字证书的验证以及加密密钥的生成
防止了服务器端的一直等待而浪费资源。
简单描述
客户端发送中断连接请求,也就是发送 FIN 报文。
服务端发送 ACK
wait:这个时候客户端进入 FIN_WAIT 状态,继续等待服务端的 FIN 报文
当服务端确定数据已发送完成,则向客户端发送 FIN 报文
客户端收到 FIN 报文后,发送 ACK 后进入 TIME_WAIT 状态,如果服务端没有收到 ACK 则可以重传,服务端收到 ACK 后,就知道可以断开连接了。客户端等待了 2MSL 后依然没有收到回复,则证明服务端已正常关闭,客户端也关闭连接
详细描述四次挥手
刚开始双方都处于 ESTABLISHED 状态,可以是客户端,也可以是服务器端先发起关闭请求。
第一次挥手:客户端设置发送 FIN 报文,报文中会指定一个序列号。此时客户端进入FIN_WAIT_1状态,这表示客户端没有数据要发送给客户端了。 第二次挥手:服务端收到了客户端发送的 FIN 报文段,向客户端返回一个 ACK 报文段,表明自己接受到了客户端关闭连接的请求,且把客户端的序列号值+1 作为 ACK 报文的序列号值,发送完毕后服务器端进入CLOSE_WAIT状态, 客户端进入FIN_WAIT_2状态,等待服务器端关闭连接。 第三次挥手:如果服务端准备好了也想断开连接,和客户端的第一次挥手一样,发送 FIN 报文,,且指定一个序列号。发送完毕后,服务端进去LAST_ACK状态,等待来自客户端的最后一个 ACK 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己的 ACK 报文的序列号值,此时客户端处于TIME_WAIT状态,等待可能出现的要求重传的 ACK 包;服务端接收到这个确认包后,关闭连接,进入 CLOSED 状态。客户端等待一段时间(两个最大生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务端的 ACK,认为服务端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。TCP 的四次挥手就完成了。
为什么客户端发送 ACK 之后不直接关闭
要确保服务器是否已经收到了我们的 ACK 报文,如果没有收到的话,服务器会重新发 FIN 报文给客户端,客户端再次收到 FIN 报文之后,就知道之前的 ACK 报文丢失,然后再次发送 ACK 报文。