Skip to content

Commit 708198b

Browse files
authoredJul 4, 2021
update: 排版、内容
1 parent bc244d6 commit 708198b

File tree

1 file changed

+14
-15
lines changed

1 file changed

+14
-15
lines changed
 

‎WeeklyLearning/iOSWeeklyLearning_17.md

+14-15
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@
4343

4444
那么,为什么同一个字符串的 `长度` 在 String 与 NSString 中会得到不同的值呢?我们来看一下 `String.count``NSString.length` 各自的官方定义:
4545

46-
> String.count: The number of characters in a string.
47-
>
48-
> NSString.length: The length property of an NSString returns the number of UTF-16 code units in an NSString
46+
> * String.count: The number of characters in a string.
47+
> * NSString.length: The length property of an NSString returns the number of UTF-16 code units in an NSString
4948
5049
通过上述官方文字,我们隐约能察觉到一丝不同而继续发出疑问🤔️:
5150

@@ -105,22 +104,22 @@ print((combinedEAcute as NSString).length) // 2
105104
* ACK:表示前面确认号字段是否有效。ACK=1 代表有效。带 ACK 标志的 TCP 报文段称为确认报文段;
106105
* FIN:表示通知对方本端数据已发送完毕,要关闭连接了。带 FIN 标志的 TCP 报文段称为终止报文段。
107106

108-
三次握手是指建立一个 TCP 连接时,需要客户端和服务端总共发送 3 个包,需要三次握手才能确认双方的接收与发送能力是否正常。
107+
**三次握手是指建立一个 TCP 连接时,需要客户端和服务端总共发送 3 个包,需要三次握手才能确认双方的接收与发送能力是否正常。**
109108

110109
![](https://gitee.com/zhangferry/Images/raw/master/iOSWeeklyLearning/20210703051424.png)
111110

112-
* 第一次握手:客户端向服务端发起连接请求,需要发送一个 SYN 报文到服务端。
113-
* 第二次握手:当服务端收到客户端发过来的 SYN 报文后,返回给客户端 SYN、ACK 报文。`这时候服务端可以确认客户端的发送能力和自己的接收能力正常`
114-
* 第三次握手:客户端收到该报文。`这时候客户端可以确认双方的发送和接收能力都正常`。然后客户端再回复 ACK 报文给服务端,服务端收到该报文。`这时候服务端可以确认客户端的接收能力和自己的发送能力正常。所以这时候双方都可以确认自己和对方的接收与发送能力都正常`。就这样客户端和服务端通过 TCP 建立了连接。
111+
1. 客户端向服务端发起连接请求,需要发送一个 SYN 报文到服务端。
112+
2. 当服务端收到客户端发过来的 SYN 报文后,返回给客户端 SYN、ACK 报文。`这时候服务端可以确认客户端的发送能力和自己的接收能力正常`
113+
3. 客户端收到该报文。`这时候客户端可以确认双方的发送和接收能力都正常`。然后客户端再回复 ACK 报文给服务端,服务端收到该报文。`这时候服务端可以确认客户端的接收能力和自己的发送能力正常。所以这时候双方都可以确认自己和对方的接收与发送能力都正常`。就这样客户端和服务端通过 TCP 建立了连接。
115114

116-
四次挥手的目的是关闭一个 TCP 连接。
115+
**四次挥手的目的是关闭一个 TCP 连接。**
117116

118117
![](https://gitee.com/zhangferry/Images/raw/master/iOSWeeklyLearning/20210703051443.png)
119118

120-
* 第一次挥手:客户端主动发起连接断开,发送一个 FIN 报文到服务端;
121-
* 第二次挥手:服务端返回给客户端 ACK 报文。此时服务端处于关闭等待状态,而不是立马给客户端发 FIN 报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。`此时客户端到服务端的连接已经断开。但客户端和服务端之间所建立的 TCP 连接通道是全双工的,此时只是处于半关闭状态,所以服务端到客户端可能还会传递数据`
122-
* 第三次挥手:当服务端的数据都发送完毕后,给客户端发送一个 FIN,ACK 报文;
123-
* 第四次挥手:客户端回应一个 ACK 报文。注意客户端发出 ACK 报文后不是立马释放 TCP 连接,而是要经过 2MSL(最长报文段寿命的 2 倍时长)后才释放 TCP 连接。而服务端一旦收到客户端发出的确认报文就会立马释放 TCP 连接,所以服务端结束 TCP 连接的时间要比客户端早一些。`此时服务端到客户端的连接也已经断开,整个 TCP 连接关闭`
119+
1. 客户端主动发起连接断开,发送一个 FIN 报文到服务端;
120+
2. 服务端返回给客户端 ACK 报文。此时服务端处于关闭等待状态,而不是立马给客户端发 FIN 报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。`此时客户端到服务端的连接已经断开。但客户端和服务端之间所建立的 TCP 连接通道是全双工的,此时只是处于半关闭状态,所以服务端到客户端可能还会传递数据`
121+
3. 当服务端的数据都发送完毕后,给客户端发送一个 FIN,ACK 报文;
122+
4. 客户端回应一个 ACK 报文。注意客户端发出 ACK 报文后不是立马释放 TCP 连接,而是要经过 2MSL(最长报文段寿命的 2 倍时长)后才释放 TCP 连接。而服务端一旦收到客户端发出的确认报文就会立马释放 TCP 连接,所以服务端结束 TCP 连接的时间要比客户端早一些。`此时服务端到客户端的连接也已经断开,整个 TCP 连接关闭`
124123

125124

126125
### 为什么 TCP 连接是三次握手?两次不可以吗?
@@ -129,17 +128,17 @@ print((combinedEAcute as NSString).length) // 2
129128

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

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

134133

135134
### 为什么 TCP 连接是三次握手,关闭的时候却要四次挥手?
136135

137-
因为只有在客户端和服务端都没有数据要发送的时候才能断开 TCP。而客户端发出 FIN 报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。而服务端收到客户端的 FIN 报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的 FIN 报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发 FIN 报文(所以不能一次性将确认报文和 FIN 报文发给客户端,就是这里多出来了一次)。
136+
因为只有在客户端和服务端都没有数据要发送的时候才能断开 TCP 连接。而客户端发出 FIN 报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。而服务端收到客户端的 FIN 报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的 FIN 报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发 FIN 报文(所以不能一次性将确认报文和 FIN 报文发给客户端,就是这里多出来了一次)。
138137

139138

140139
### 为什么客户端发出第四次挥手的确认报文后要等 2MSL 的时间才能释放 TCP 连接?
141140

142-
这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认 ack 报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是 2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
141+
这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是 2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
143142

144143
参考:[https://zhuanlan.zhihu.com/p/141396896](https://zhuanlan.zhihu.com/p/141396896 "https://zhuanlan.zhihu.com/p/141396896")
145144

0 commit comments

Comments
 (0)