计算机网络系统学习精华总结(三):传输层——2(TCP三次握手、四次挥手)

本文深入解析TCP协议的关键机制,包括拥塞控制的慢启动算法和拥塞避免算法,三次握手建立连接的过程,以及四次挥手断开连接的细节。同时介绍了套接字编程的基本概念和流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       (1) TCP协议的拥塞控制:流量控制考虑点对点的通信量的控制,而拥塞控制考虑的是整个网络,是全局性的控制。TCP的拥塞控制是慢启动算法和拥塞避免算法相互配合产生的结果。

        慢启动算法:1)从小到大逐渐增加发送数据量;2)每收到一个报文确认,发送量翻倍;比如1,2,4,8,16,32......M(慢启动阈值)。
        拥塞避免算法:1)来维护一个拥塞窗口的变量;2)只要网络不拥塞,就试探着将拥塞窗口调大。是在达到慢启动阈值之后开始工作的,比如1,2,4,8,16,32......M(慢启动阈值),M+1,M+2,M+3......       前面是慢启动算法,达到慢启动阈值后,拥塞避免算法开始工作。

       (2) TCP连接的三次握手(连接建立过程)

       需要用到的标志位:SYN——同步位,为1时表示请求连接报文(发送方请求连接,接收方确认连接);ACK——确认位,为1时确认号生效;FIN——终止位,FIN为1时,表示释放连接。

        首先,发送方发送请求报文(SYN=1,序号seq=x),接收方监听到该报文并回应(SYN=1,序号seq=y和确认号ack=x+1) ,发送方确认连接(ACK=1,序号seq=x+1,确认号ack=y+1)。为什么需要三次握手,两次行不行?三次握手是为了避免已经失效的连接请求报文又重新传送到接收方,引起错误。

      (3)TCP断开连接(4次挥手)

        数据传输完成后,释放连接需要经过四次挥手过程:

       挥手过程:发送方发送释放连接请求(FIN=1,seq=u),接收方接收后确认(ACK=1,seq=v,ack=u+1), 此时可能服务端还有消息未发送完成,因此此时处于关闭等待期间,待消息发送完成后,发送确认释放消息(FIN=1,ACK=1,seq=w,ack=u+1),发送方接收该消息后,开启等待计时器(主动释放这方不立即进入关闭状态,计时期间不释放端口)。

       等待计时器设置时间一般为2MSL(2倍的最长报文段时间)的原因:1)最后一个报文还没有确认(第四次挥手报文),确保第四次挥手的ACK可以达到接收方;2)2MSL时间内没有收到,则接收方会重发,重新进行第三次挥手(接收方认为第三次挥手的信息没有被发送方接收到);3)确保当前的报文都过期了。

       (4)套接字与套接字编程

        网络通信中,使用端口(port)来标记不同的网络进程,用16bits表示(0-65535),用IP地址来标记一台主机,那么IP+端口号便可以标识一台主机中的某一个网络进程。{IP:端口}即为一个套接字(Socket),表示TCP连接的一端,通过套接字编程可以进行数据发送和接收。TCP连接由两个套接字组成:

        服务端:创建套接字(socket)——绑定套接字(bind)——监听套接字(listen)———接收处理消息;

        客户端:创建套接字(socket)——连接套接字(connect)——发送消息;

        单机通信采用域套接字方法;多机器,跨网络采用网络套接字编程(走协议栈)

         最后介绍下保活定时器:为了保活TCP连接而设计的,保活定时器可以防止TCP连接的两端出现长时间的空闲,当一方出现状态变化或者故障时,另一方没有察觉的情况。服务器端一般会设置一个保活计时器,每次收到对方的数据则重置这个定时器,如果定时器超时,服务端则发送探测报文段,探测客户端是否在线,如果没有收到响应的话则认为客户端已经断开连接了,因此服务端也会终止这个链接。(下期发布socket套接字编程的实现代码,了解socket套接字编程,结合本章内容更能加深印象)

 

### TCP三次握手的过程 TCP协议通过三次握手建立可靠的连接。具体来说: - 客户端发起请求,发送带有SYN标志的数据包给服务器,并进入SYN_SEND状态;此时序列号设为x[^1]。 - 服务器接收到该数据包后返回一个带有SYN和ACK标志的数据包作为应答,表示同意通信并设置自己的初始序列为y,同时对客户端的序列号加一确认(即ack=x+1),随后进入SYN_RECV状态[^2]。 - 当客户端收到来自服务端的SYN/ACK响应之后,再回传一次普通的ACK报文给对方用于最终确认,其中包含着对于之前接收消息的认可编号(ack=y+1)。当这一步完成后,双方都进入了ESTABLISHED阶段,意味着一条完整的双向通道已经形成可以开始正常传输应用层数据了。 ```python # Python伪代码展示三次握手流程简化版 client_seq = random.randint(0, 2**32 - 1) # 初始化随机序列号x server_seq = None # 服务器初始化序列号为空 def client_send_syn(): global client_seq send_packet('SYN', seq=client_seq) def server_receive_syn_and_reply_ack(): global server_seq received_data = receive_packet() if 'SYN' in received_data.flags: server_seq = random.randint(0, 2**32 - 1) reply_with_syn_ack(received_data.seq + 1, server_seq) def client_final_confirmation(server_initial_seq): confirm_server_init_seq_is_correct = True if confirm_server_init_seq_is_correct: send_packet('ACK', ack_num=(server_initial_seq + 1)) ``` ### 关于为何需要三次握手的原因 为了确保两端都能够正确无误地建立起连接关系而不丢失任何一方的信息,在计算机网络环境中存在着各种不确定因素可能导致某些分组在网络上传输失败或者延迟到达等问题发生。因此采用步验证机制来保证每一次尝试都能得到及时反馈从而提高整个系统的可靠性。 ### 四次挥手断开连接的理由 由于TCP是一个面向字节流而非长度固定的记录或帧的服务模型,所以在结束会话时必须明确告知另一方不再有新的数据要传送出去。为此引入了FIN旗标用来标记某方向上的终止意图。然而仅仅依靠单方面声明还不够充分——还需要等待一段时间以确保所有已发出但尚未被处理过的段落均已被接收者获取到手才行。这就解释了为什么关闭操作要比启动复杂得多,通常涉及到四个独立的动作才能彻底切断联系。 ### 面试中的常见问题 针对上述知识点,面试官可能会询问如下几个方面的问题: 1. 描述一下什么是TCP三次握手?其目的是什么? 2. 如果只做两次握手能否实现可靠连接建立呢?如果不行的话缺少哪部分保障? 3. 解释下四次挥手中的每一个步骤以及它们各自的作用是什么样的. 4. 在实际应用场景里如何优化TCP建连效率减少RTT往返时间的影响?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值