Transport Layer 记录层
一个经典问题,什么时候用UDP,什么时候用TCP. QQ 为什么以 UDP 协议为主,以 TCP 协议为辅?
实际上要考虑历史的发展: https://www.zhihu.com/question/20292749
某次架构师大会上那个58同城做即时通信的人说:原因是因为当时没有epoll这种可以支持成千上万tcp并发连接的技术,所以他们使用了udp,然后在udp上面封装了一下,模拟了一下tcp,解决了大并发的问题,之后因为做的很nb了,虽然epoll这种技术出现了,还是没有改回使用tcp了.现在再做类似的东西就不需要使用udp了.这个说法应该比较可信的.
作者:解灵运
链接:https://www.zhihu.com/question/20292749/answer/24557541
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
TCP 记录
两个重要的方法
- Flow Control:控制
发送方-接收方之间的速度差异 -
Congestion Control:控制整个网络之间的速度差异
-
流量控制(flow control):所说的端到端(end to end)针对的是发送方和接收方速度不匹配的问题比如经典的fast sender and slow receiver问题,接收方缓存大小与发送速率不匹配,提供一种速度匹配服务遏制发送速率使接收方应用程序的读取速率与之相适应。
-
拥塞控制就是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。
-
流量控制:经典的,用可变窗口来做
- 拥塞控制:经典的,拥塞串口,慢开始、快重传、快恢复
PS: 这一块真是无底洞,深究起来各种论文....
握手挥手
- TCP 为什么三次握手
- TCP 为什么是四次挥手,第二阶段和第三阶段为什么不能合并为 (ACK+FIN)
其他问题
TCP 为什么要校验?
网络分层思想,毕竟当时 Unix 的小而美思想是计算机界的绝对统治地位。但现在有融合的趋势,比如 IPv6 就不强制校验。(题外话,最典型的就是微软、systemctl 这些事物,都体现了计算机界思想的一个变化)
TCP Checksum 为什么要加上伪首部
伪首部也就是有 IP 地址和报文长度,这个破坏了分层思想,因为用了 IP 层的信息。
简单来说,这是历史的问题:
1. 设计者认为源地址和目的地址对 IP 和 TCP 两个层都有意义。这两个层之间紧密相关。TCP 应用肯定会对 IP 地址进行一些检查等操作。并且避免冗余,就用了伪首部。
(The Source Address, Destination address, length, etc. are part of the meaning of the TCP frame - in that the end point machines use that information in the TCP application.)
-
本来打算是把 TCP 设计为比较安全的协议,因为它是一种端到端的协议。方式就是使用 DSA 加密算法对 TCP 进行比较好的身份验证。这样可以有效防止中间人攻击,checksum 的防护并不是特别好。
(This would protect against a man-n-the-middle attack that delivered valid packets with an incorrect source address, etc. (yes, to be truly reliable, we would have had to use a DSA instead of the current checksum).)
-
但是最后没有加密了,为什么呢?因为 NAT!NAT 本质上就是中间人攻击,所以没办了,最后那个加密字段还是变成了 checksum,所以里面包含的 IP 信息在 IP 层已经 checksum 过了,造成了令人困惑的冗余检查。
(This was a careful design decision, wrecked irrevocably by the terrorists who invented NAT (which doesn't allow end--to-end encryption, because NAT is inherently a "man-in-the-middle" attack!).)
http://www.postel.org/pipermail/end2end-interest/2005-February/004616.html
- TimeOut 计算
- 持续定时器的目的是为了解决死锁,但是不是很理解这个为什么会导致死锁:
- 此时接收方不会重传,因为 tcp 规定对于没有携带数据的 ACK 确认报文段不会进行重传