TCP 与 UDP
Contents
TCP 数据段格式
传输层建立【端口 -> 端口】之间的通信,网络层建立【主机 -> 主机】之间的通信。
- 序列号:
TCP把连接中发送到所有数据,按字节进行编号。当 SYN=1 时,序列号seq就是报文段中第一个字节的数据编号。 - 确认号:是当前报文段的最后一个字节编号+1,也就是下一个报文段的序列号。确认号表示,已接受小于该确认号的所有数据。
- 窗口: 窗口大小是
TCP接受缓冲区的剩余大小,用来进行流量控制。发送方不能够发送超过对方窗口大小的数据,否则会被丢掉。
TCP 与 UDP 区别
TCP是面向连接的;而UDP是不需要建立连接,即发送数据之前不需要建立连接。
TCP是可靠的,它保证数据的正确性;而UDP是不可靠的,可能会丢包。
UDP的实时性强,工作效率比TCP高,适用于高速传输和实时性要求比较高的通信或者广播通信。
TCP是点对点连接;UDP支持多对多的交互通信。
TCP对系统资源要求较高;UDP对系统资源要求较少。
TCP 为什么是可靠连接?
TCP都有一个发送缓冲区和一个接受缓冲区。
TCP数据段里的序列号 Seq 能使TCP保证按序到达。TCP数据段里的确认号 Ack 能使TCP保证不丢包,超时了会重传。TCP拥有 流量控制 机制,TCP数据段里还有一个2个字节的窗口字段,它表示 接受缓冲区 里的剩余空间,发送方 根据这个窗口里的大小,发送比窗口小的数据量,否则发送的数据会被丢掉。这几点让TCP能够保证可靠连接。
TCP拥有 拥塞控制 机制。
UDP 为什么是不可靠的?
UDP没有发送缓冲区,只有一个接受缓冲区。所以只要有数据就会发送,不管对方能不能接受。当对方的接受缓冲区满了之后,新来的数据就会被丢掉,UDP是没有流量控制的,也没有确认号,所以UDP是不可靠的。
TCP 三次握手

- 第一次握手:客户端将标识位 SYN 设置为 1,并且随机产生一个值 x,令
seq = x,把报文段发送给服务端。
- 第二次握手:服务端看到 SYN = 1 就知道它是要请求建立连接,服务端把 SYN 和 ACK 都设置为 1,并且令
ack = x + 1,随机生成一个值 y,令seq = y,告诉对方它的序列号。
- 第三次握手:客服端收到数据段后检查 ACK 是否为 1,
ack == x + 1?如果是,就把标志位 ACK 设置为 1,令ack = y + 1,并且发送给服务端,服务端也做同样的判断后,如果正确,就说明连接建立成功。客户端与服务端之间可以开始传输数据了。
TCP 四次挥手

- 第一次挥手:客户端将标志位 FIN 设置为 1,用来断开与服务端的数据传输。
- 第二次挥手:服务端收到对方的关闭连接请求之后,发送一个确认号,确认号 ack 等于对方的序列号 seq + 1.
- 第三次挥手:同上。
- 第四次挥手:同上。
为什么建立连接是三次握手,而关闭连接是四次挥手?
因为三次握手时,可以把标志位 SYN 和 ACK 放在同一个报文段发送。
但关闭连接时,当收到对方的 FIN 通知时,它仅仅表示着对方已经没有数据发送了,但可能,我还有没把全部数据发送给对方。所以不能立马把 socket 连接关闭掉,等我把数据全部发送完之后,再发送 FIN 通知,如果收到对方的确认号了,就说明双方的连接都关闭了。所以在大多数情况下,FIN 和 ACK 报文段是分开发送的。
为什么不能用两次握手进行连接?
因为 两次握手 只能得到一方的确认,而TCP连接就是为了,让双方彼此知道对方可以正确地接受数据了,并且协商双方的初始序列号。所以TCP连接一定需要 三次握手,不能 两次握手。
为什么 TIME_WAIT 状态需要经过 2MSL 才能进入 CLOSED 状态?
因为在第四次挥手时发送的 ACK 报文段可能在传输过程中丢失,如果服务端没有收到 ACK 就会重新发送 FIN 报文段。所以客户端至少要等一次发送和一次回复所需要的最大时间,也就是 2MSL.
MSL (Maximum Segment Lifetime):报文段在网络中的最长生存时间。