编程语言只是一种工具,它不应该成为我们技术前进之路上的壁垒。

TCP 笔记整理 (总)

1)TCP header format:https://www.cnblogs.com/christmad/p/11478758.html

2)TCP 建立连接 为什么是三次握手:https://www.cnblogs.com/christmad/p/11478795.html

3)TCP 断开连接 四次挥手:https://www.cnblogs.com/christmad/p/11478799.html

4)TCP 流量控制:https://www.cnblogs.com/christmad/p/11478802.html

5)TCP 拥塞控制:https://www.cnblogs.com/christmad/p/11478807.html

 

最初学习时整的笔记,有些内容可能还缺乏归纳整理,有错误或没有关联对的地方欢迎各位大佬和童鞋们指出~

 

简单QA:

Q:TCP为什么称为“可靠协议”?

A:“可靠”是相对于什么来说的?根据(https://www.brianstorti.com/tcp-flow-control/)此文中的开篇段落“TCP is the protocol that guarantees we can have a reliable communication channel over an unreliable network. When we send data from a node to another, packets can be lost, they can arrive out of order, the network can be congested or the receiver node can be overloaded. ”,我们知道,原来,不可靠的是网络(网络抖动丢包、接收者缓冲区溢出而丢包、网络包错序到达 等),所以TCP设计的初衷就是为了要达成“稳定的网络传输”这个目标。

 

Q:TCP 流量控制和拥塞控制是什么关系?

A:流量控制(sliding-window)和拥塞控制(congestion control)是 TCP 设计时为连接双方设计的“友好”进行网络信息传输的机制。简单来说,流量控制在接收方,拥塞控制在发送方。这样一来TCP两端能够互相协调,共同建立一个在网络上奔跑的“友好”的通道(TCP协议在发生拥塞时,优先牺牲自己)。

流量控制指的是接收方有义务告诉发送方当前自己所能承受的网络传输速度,它通过一个滑动窗口参数(放在请求头),不停地通知发送方当前自己的网络缓冲区还有多少空间,以便发送方控制发送网络包的速度。对接收方来说,应用处理网络包的速度越快,缓冲区所富裕的用于接收新网络包的空间就越大,如果接收方迟迟不处理缓冲区的数据,一旦缓冲区满,发送方将收到一个 zero window 的包,此时 TCP 协议中的发送方就会停止发送新数据,并以 ZWP(zero window probe)包探测何时才能继续开始传输数据。

拥塞控制指的是发送方主动探测网络上的情况,及时发现网络拥堵的情况,在发现拥堵后降低发送速率,并启动重传工作,重传丢失的网络数据包。在拥塞控制算法不断更新的当下,已经补充了快重传、快恢复等算法来支持在网络包超时判断之前、网络包超时之后等情况快速进行网络包的处理。

 

Q:服务器使用 TCP 作为传输协议并建立连接后,是如何区分不同客户端连接的?在此基础上客户端连接收发的包是怎么保证有序的?

A:

对前半个问题,我们首先回忆一下 tcp header format 内容,https://www.cnblogs.com/christmad/p/11478758.html

其中我们要用到 source port,destination port,sequence number 这几个字段。假设服务器是一个 HTTP 服务,建立连接时客户端使用操作系统随机分配的端口首先向服务器的 80端口发起访问,3次握手成功后,服务器这边会用另外一个端口将这条连接标记起来,即客户端发起时 source port 假设是 12345,destination port 是 80,连接建立后服务器这边会另外用一个端口假设是 54321 记录这条连接,因此在服务器端记录一条连接可能保存了两种映射关系,第一个映射是 12345->80, 第二个映射是 80->54321。为什么是两个映射关系,我的猜测依据是“操作系统标识一条连接是通过一个五元组关系确定的”,因此 80 端口作为 http 协议的标识在这之中起到一定的作用,所以类似 linux 这样的操作系统会保存这样的两个映射来确定这条连接(socket)是用了什么协议。在五元组基础上,端口是可以被不同协议复用的,这里就不多展开了,不清楚的同学可以自行搜索一下相关知识。

综上,通过在 TCP packet 中的 source port 和 destination port,linux服务器能够区分从网络上接收到的包来自哪一条具体的连接。

对于后半个问题,其乱序产生的原因是由于网络硬件环境的复杂性造成的,在网络包路由的过程中并不能保证先发送的包到达,虽然在发送方肯定是按照序号发送出去的,但由于中间路由途径的不确定性,仍然会有乱序问题发生。

TCP协议能够在连接上保证包有序,即使乱序到达的包也能正确组装,依靠的是 sequence number 字段。在三次握手过程中客户端和服务器都已经互换了双方的初始 sequence number 值。通过将每一次发送出去的包 sequence number 加 1,即给包打上编号,在接收方则可以通过这个编号将网络包正确的组装起来,也就不会发生乱序的问题了。(三次握手笔记:https://www.cnblogs.com/christmad/p/11478795.html

 

posted on 2019-09-06 23:22  独角没有戏  阅读(227)  评论(0编辑  收藏  举报

导航