阿浪最近闭关修炼,每每想使 JAVA 大法更上一层楼,丹田里的码力却后继无力。于是遍访名师,拜入了江湖最近风头正盛的混元太极门 —— 马老师门下。


愈接近马老师愈发现马老师渊博,今日授我《网络五连鞭》荡平天下宵小。

课前小知识 ( TCP 报文头 )

  1. 序号:seq 序号;占 32 位,用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。

  2. 确认序号:ack 序号;占 32 位,只有 ACK 标志位为 1 时,确认序号字段才有效,ack = seq + 1。

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

# 1、为什么 TCP 连接的时候是 3 次?

在学习《计算机网络》的时候,我想大家都听过三次握手,那我就问马老师了,什么是三次握手?

  • 第一次握手:
    客户端要向服务端发起连接请求,首先客户端随机生成一个起始序列号 ISN (比如是 100),那客户端向服务端发送的报文段包含 SYN 标志位 (也就是 SYN=1),序列号 seq=100。

  • 第二次握手:
    服务端收到客户端发过来的报文后,发现 SYN=1,知道这是一个连接请求,于是将客户端的起始序列号 100 存起来,并且随机生成一个服务端的起始序列号 (比如是 300)。然后给客户端回复一段报文,回复报文包含 SYN 和 ACK 标志 (SYN=1,ACK=1)、序列号 seq=300、确认号 ack=101 (客户端发过来的序列号 + 1)。

  • 第三次握手:
    客户端收到服务端的回复后发现 ACK=1 并且 ack=101, 于是知道服务端已经收到了序列号为 100 的那段报文;同时发现 SYN=1,知道了服务端同意了这次连接,于是就将服务端的序列号 300 给存下来。

然后客户端再回复一段报文给服务端,报文包含 ACK 标志位 (ACK=1)、ack=301 (服务端序列号 + 1)、seq=101 (第一次握手时发送报文是占据一个序列号的,所以这次 seq 就从 101 开始,需要注意的是不携带数据的 ACK 报文是不占据序列号的,所以后面第一次正式发送数据时 seq 还是 101)。

当服务端收到报文后发现 ACK=1 并且 ack=301,就知道客户端收到序列号为 300 的报文了,就这样客户端和服务端通过 TCP 建立了连接。

# 马老师,TCP 只握手 2 次不可以吗?

马老师说因为需要考虑连接时丢包的问题,如果只握手 2 次,第二次握手时如果服务端发给客户端的确认报文段丢失,此时服务端已经准备好了收发数据 (可以理解服务端已经连接成功),而客户端一直没收到服务端的确认报文,所以客户端就不知道服务端是否已经准备好了 (可以理解为客户端未连接成功),这种情况下客户端不会给服务端发数据,也会忽略服务端发过来的数据。

如果是三次握手,即便发生丢包也不会有问题,比如如果第三次握手客户端发的确认 ACK 报文丢失,服务端在一段时间内没有收到确认 ACK 报文的话就会重新进行第二次握手,也就是服务端会重发 SYN 报文段,客户端收到重发的报文段后会再次给服务端发送确认 ACK 报文。

# 2、为什么 TCP 连接的时候是 3 次,关闭的时候却是 4 次?

因为只有在客户端和服务端都没有数据要发送的时候才能断开 TCP。而客户端发出 FIN 报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。

而服务端收到客户端的 FIN 报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的 FIN 报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发 FIN 报文 (所以不能一次性将确认报文和 FIN 报文发给客户端,就是这里多出来了一次)。

# 马老师,四次挥手都干吗了?

马老师看我满脸懵懂,于是背着师兄又给我开了个小灶,补一补四次挥手的要诀。

  • 第一次挥手:
    当客户端的数据都传输完成后,客户端向服务端发出连接释放报文 (当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含 FIN 标志位 (FIN=1)、序列号 seq=1101 (100+1+1000,其中的 1 是建立连接时占的一个序列号)。需要注意的是客户端发出 FIN 报文段后只是不能发数据了,但是还可以正常收数据;另外 FIN 报文段即使不携带数据也要占据一个序列号。

  • 第二次挥手:
    服务端收到客户端发的 FIN 报文后给客户端回复确认报文,确认报文包含 ACK 标志位 (ACK=1)、确认号 ack=1102 (客户端 FIN 报文序列号 1101+1)、序列号 seq=2300 (300+2000)。此时服务端处于关闭等待状态,而不是立马给客户端发 FIN 报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。

  • 第三次挥手:
    服务端将最后数据 (比如 50 个字节) 发送完毕后就向客户端发出连接释放报文,报文包含 FIN 和 ACK 标志位 (FIN=1,ACK=1)、确认号和第二次挥手一样 ack=1102、序列号 seq=2350 (2300+50)。

  • 第四次挥手:
    客户端收到服务端发的 FIN 报文后,向服务端发出确认报文,确认报文包含 ACK 标志位 (ACK=1)、确认号 ack=2351、序列号 seq=1102。注意客户端发出确认报文后不是立马释放 TCP 连接,而是要经过 2MSL (最长报文段寿命的 2 倍时长) 后才释放 TCP 连接。而服务端一旦收到客户端发出的确认报文就会立马释放 TCP 连接,所以服务端结束 TCP 连接的时间要比客户端早一些。

# 3、GET 和 POST 请求有什么区别?

因为浏览器和服务器的交互是通过 HTTP 协议执行的,而 GET 和 POST 也是 HTTP 协议中的两种方法。

GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改。

POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据。

PUT:向服务器新添加数据,就是所谓的增。

DELETE:从字面意思也能看出,这种方式就是删除服务器数据的过程。

  • Get 是不安全的,因为在传输过程,数据被放在请求的 URL 中,Post 的所有操作对用户来说都是不可见的。

  • Get 请求提交的 url 中的数据最多只能是 2048 字节,这个限制是浏览器或者服务器给添加的,http 协议并没有对 url 长度进行限制,目的是为了保证服务器和浏览器能够正常运行,防止有人恶意发送请求。Post 请求则没有大小限制。

  • GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包。

  • 对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200 (返回数据);而对于 POST,浏览器先发送 header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 ok(返回数据)。

# 4、HTTP 与 HTTPS 的区别是什么?

HTTP:互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

HTTPS:是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。

  • HTTPS 协议需要到 CA 申请证书,一般免费证书较少,因而需要一定费用。

  • HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。

  • HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

  • HTTP 的连接很简单,是无状态的。HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。

# 5、为什么使用 HTTP 的 RESTful 取代了多协议的 Web-Service?

马老师:今日为师已经传授你过多本门秘法,所谓贪多嚼不烂、师傅领进门修行在个人。这就作为你的思考题,让为师看看你对我马家功法的悟性是高是低。

阿浪:马老师你不讲武德!!!

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

西门阿杰 微信支付

微信支付

西门阿杰 支付宝

支付宝