http的自我总结(1)---TCP/IP协议

基础概念

一般的,我们把计算机网络分成了5层,分别是物理层,数据链路层,网络层,运输层,应用层(ISO是七层模型,TCP/IP是四层模型),而我们使用的HTTP协议就是属于应用层,当然互联中的应用层协议还有很多,如域名系统的DNS,支持电子邮件的SMTP协议的等等。以下图三种协议的区别:

在这里插入图片描述

关于TCP协议

其实在web通信中,不仅需要HTTP协议,还需要其他协议的,TCP是其中一种。在进行http之前是要先建立起TCP连接,连接Web浏览器首先要通过网络与Web服务器建立连接,该连接就是通过TCP来完成的。HTTP是比TCP更高层次的应用层协议,根据规则, 只有低层协议建立之后才能,才能进行更高层协议的连接。TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接。采用4次挥手来关闭一个连接。

TCP 之所以可靠,大体上由于以下原因:

1.数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时 TCP 发送数据端超时后会重发数据;

2.对失序数据包重排序:TCP 报文段使用 IP 数据报来传输,而IP不提供保证次序正确的功能,因此IP 数据报的到达可能会失序,导致TCP 报文段的到达也可能会失序。由于TCP是一个字节流协议,绝不会以杂乱的次序给上层程序发送数据,所以TCP 将对失序数据进行重新排序,然后才交给应用层;其实这都归功于TCP头部的序列号。

3.丢弃重复数据:对于重复数据,能够丢弃重复数据;这个造成的原因跟第二点是差不多的,都是由于IP不提供重复消除的功能。

4.应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;ACK是累积的,一个确认字节号N的ACK表示所有直到N的字节(不包括N)已经成功被接收了。这样的好处是如果一个ACK丢失,很可能后续的ACK就足以确认前面的报文段了。

5.超时重发:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;

6.流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制

借用图解 HTTP 一书中的图文:

发送端在层与层之间传输数据时,每经过一层必定会加上一个该层的首部信息。反之,接收端在层与层之间传输数据时,每经过一层会把相关的首部信息去掉。

在这里插入图片描述

TCP三次握手

TCP协议采用了三次握手的方式来保证数据的准确运输。三次握手的作用就是请求方和接收方都能明确自己和对方的收和发的能力是正常的。其实3次握手的目的并不只是让通信双方都了解到一个连接正在建立,还在于利用数据包的选项来传输特殊的信息,交换初始序列号。

在这里插入图片描述

术语版本:

第一次握手:建立连接时,向服务器发出连接请求报文,这是报文首部中的同部位 SYN = 1,同时指明客户端的初始序列号 seq = x ,客户端进程进入了 SYN-SENT (同步已发送状态)状态,等待服务器确认;
​ **第二次握手:**服务器收到 syn 包后,如果同意连接,则发出确认报文; 确认报文 ACK = 1,SYN = 1,为了确认客户端的SYN,确认号是 ack = x + 1,将客户端的序列号+1作为ack的值,这样每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传,同时也要为自己初始化一个序列号 seq = y,此时服务器进程进入了 SYN-RCVD(同步收到)状态;
​ **第三次握手:**客户端收到服务器的 SYN+ACK 包,要向服务器给出确认。确认报文的标志 ACK = 1,ack = y + 1,为了确认服务器端的SYN,客户端将对方的序列号+1作为返回的ack数值,将自己的序列号 seq = x + 1,此时,TCP 连接建立,客户端进入 ESTABLISHED (已建立连接)状态

注:
seq:“sequance” 序列号;
ack:“acknowledge” 确认号;
SYN:“synchronize” 请求同步标志;
ACK:“acknowledge” 确认标志;
FIN:“Finally” 结束标志。

通俗易懂版本:

第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。 从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。

第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。 第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。

经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。

**注:**这里有个问题,就是为啥不能是两次握手,其实也很简单,如果没了第三次握手的话,接收方根本不知道发送方的接收功能有没有问题。为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤,如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

TCP四次挥手

建立一个连接需要三次握手,而终止一个连接要经过四次挥手,这是由 TCP 的半关闭(half-close)造成的。

在这里插入图片描述

术语版本:

第一次挥手:客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部 FIN=1,其序列号为 seq = u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入 FIN-WAIT-1(终止等待1)状态。

**第二次挥手:**服务器收到连接释放报文,发出确认报文,ACK = 1,ack = u + 1,并且带上自己的序列号 seq = v,此时,服务端就进入了 CLOSE-WAIT(关闭等待)状态。

TCP 服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个 CLOSE-WAIT 状态持续的时间。
客户端收到服务器的确认请求后,此时,客户端就进入 FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

第三次挥手:
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN = 1,ack = u + 1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为 seq = w,此时,服务器就进入了 LAST-ACK(最后确认)状态,等待客户端的确认。

第四次挥手:
客户端收到服务器的连接释放报文后,必须发出确认,ACK = 1,ack = w + 1,而自己的序列号是 seq = u + 1,此时,客户端就进入了 TIME-WAIT(时间等待)状态。

注意此时 TCP 连接还没有释放,必须经过 2MSL(最长报文段寿命)的时间后,当客户端撤销相应的 TCB 后,才进入 CLOSED 状态。

服务器只要收到了客户端发出的确认,立即进入 CLOSED 状态。同样,撤销 TCB 后,就结束了这次的 TCP 连接。

可以看到,服务器结束 TCP 连接的时间要比客户端早一些。

通俗易懂版本:

TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。注意,接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”

**注:**这里也有个问题,就是为啥建立连接是三次握手,断开连接是四次挥手呢?这是因为在建立连接时,服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后,它可以把 ACK 和 SYN(ACK 起应答作用,而 SYN 起同步作用)放在一个报文里来发送。 但关闭连接时,当收到对方的 FIN 报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你未必会马上会关闭 SOCKET ,也即你可能还需要发送一些数据给对方之后,再发送 FIN 报文给对方来表示你同意现在可以关闭连接了,所以它这里的 ACK 报文和 FIN 报文多数情况下都是分开发送的。

另外由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个 FIN 来终止这个方向的连接。收到一个 FIN 只意味着这一方向上没有数据流动,一个 TCP 连接在收到一个 FIN 后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

TCP相关小知识点

在HTTP1.0默认是每进行一次HTTP通信都要建立一个TCP连接,那样开销会很大,所以就可以在请求报文加上Connection : Keep-Alive字段来使得建立一次TCP连接就可以进行多次HTTP通信。但是后来HTTP1.1都是默认长连接,就是建立一次TCP连接就可以进行多次HTTP通信,如要断开,要使用Connection : close

关于IP协议

IP协议把我们的产生的数据包发送给对方,IP地址指明了节点被分配的地址,但IP地址可能会变换,我们可以使用ARP协议来将IP地址反射为MAC地址。MAC地址是不会更改的,是网卡所属的固定地址。在找到通信目的地之前,我们是需要不断的中转的,这过程我们称作为:“路由中转”,我们并不知道路由中转了多少次的。因此是不能全面了解到互联网中的传输状况的。

通常我们在浏览器输入url后,接下来就会进行DNS域名解析。由于ip数字不方便记忆,所以就产生了域名,DNS就是帮我们找域名对应的那个ip地址。具体查找过程如下:

1.浏览器搜索自己的 DNS 缓存(浏览器维护一张域名与 IP 地址的对应表);如果没有命中,进入下一步;

2.搜索操作系统中的 DNS 缓存;如果没有命中,进入下一步;

3.搜索操作系统的 hosts 文件( Windows 环境下,维护一张域名与 IP 地址的对应表);如果没有命中,进入下一步;

  1. 操作系统将域名发送至 LDNS (本地区域名服务器),LDNS 查询自己的 DNS 缓存(一般命中率在 80% 左右),查找成功则返回结果,失败则发起一个迭代 DNS 解析请求:
  2. LDNS向 Root Name Server(根域名服务器,如com、net、im 等的顶级域名服务器的地址)发起请求,此处,Root Name Server 返回 im 域的顶级域名服务器的地址;
  3. LDNS 向 im 域的顶级域名服务器发起请求,返回 juejin.im 域名服务器地址;
  4. LDNS 向 juejin.im 域名服务器发起请求,得到 juejin.im 的 IP 地址;
  5. LDNS 将得到的 IP 地址返回给操作系统,同时自己也将 IP 地址缓存起来;操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来。

以上先总结了一下TCP/IP协议,还有的看第二节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值