网络编程基础(1):TCP/IP协议重点知识回顾
在讲解具体的网络编程前,重点回顾一下TCP/IP协议,这是Socket编程的底层支持,建立网络的基本认知。
IP协议
网络层负责数据包的选路和转发。其中最为核心的就是IP协议。
基本概念:IP协议根据数据包的目的IP地址来决定如何投递它。如果数据包不能直接发送给目标主机,那么IP协议为它寻找一个合适的下一跳(next hop)路由器,并递归进行该过程,数据包最终到达目标主机。
另补充一个ICMP协议
同样是网络层的协议,ICMP主要用于检测网络的连接。
主要有两类,一类是回应网络错误,当网络中出现意外问题,返回一个回应报文。
另一类是发送信息前,查询相关网络环境,例如ping程序查看目标是否可达。
TCP协议
传输层为两台主机上的应用程序提供端到端的通信,传输层只关心起始端(发送端)和目的端,而不在乎中转过程。传输层的核心协议有两个:TCP协议、UDP协议。此处重点讨论TCP协议的相关特性。
TCP协议采用超时重传、数据确认等方式来确保数据包被正确地发送到目的端,是可靠地服务。TCP是面向连接(事先需要建立连接)和基于流(没有数据边界)的传输协议。
面向连接
使用TCP协议通讯的双方必须先建立TCP连接。关于TCP连接的内容,最为重要的就是三次握手和四层挥手过程。如下图
基于流
所谓的基于流是指数据没有边界,发送端可以逐个字节的向数据流中写入数据,接收端也可以逐个字节的接收数据。
TCP的半关闭状态
由于TCP连接是全双工的,所以它允许两个方向的数据传输被独立关闭。假设,客户端向服务器端发送结束报文段,告诉服务器自己已经发送完所有数据,但是客户端依然可以接收服务器端发来的数据,直到服务器端也发送结束报文段以关闭连接。
在应用程序中,常见的判断对方是否已经关闭连接的方法是:read函数返回0.
在TCP协议通信中,一般情况下会经历如下的状态变化(图示如下)
重点解释TIME_WAIT状态,以及此状态维持2MSL的时间的原因。
所谓TIME_WAIT状态是,客户端收到服务器端的FIN报文,并返回ACK报文,进入此状态。主要的目的:
1.可靠的终止TCP连接,防止ACK消息丢失导致服务器端长时间无法结束连接。
2.维持2MSL时间是保证两个传输方向上所有尚未接收到的,迟到的TCP报文段都已经消失,保证之后的连接安全的建立。
超时重传
当接收端业务复杂到一直来不及处理发送端的请求时,会触发重传机制。
所谓重传机制是:TCP模块为每个TCP报文段都维护了一个重传定时器,该定时器在报文第一次发送时启动。如果超时时间内未收到应答,TCP模块将重传该报文并重置定时器。
一般而言,TCP中每次重传的超时时间都增加一倍,如第一次发送超时时间设置为0.2s,超时之后重传,设置超时时间为0.4s以此类推。而Linux中默认两个内核参数关联超时重传的次数:tcp_retries1(底层IP接管前,最少重传的次数,一般默认是3)tcp_retries1(放弃TCP连接前最多可以执行的重传次数,一般默认是15)
拥塞控制
TCP模块还有一个重要的任务,就是提高网络利用率,进行网络拥塞控制。
拥塞控制具有以下四个部分
慢启动 拥塞避免 快速重传 快速恢复
慢启动
在刚开始的时候,设定初始拥塞窗口的大小为比较小的情况,之后每收到一个ack就指数形式增加拥塞窗口的大小。当达到拥塞控制阈值(慢启动门限)时,进入拥塞避免阶段。
拥塞避免
达到阈值(慢启动门限)之后,将拥塞窗口的扩张变为线性增长模式,避免阻塞。
快速重传
是指在网络中判断网络拥塞的方案就是丢包,丢包的表现形式其一是出现超时。其二是收到重复ACK(解释:由于TCP采用的是累计确认机制,即当接收端收到比期望序号大的报文段时,便会重复发送最近一次确认的报文段的确认信号,我们称之为冗余ACK(duplicate ACK))。
- 超时发生时,认为是比较严重的网络拥塞,直接进入到慢启动阶段,且慢启动门限变为原来的一半。
- 3-ACK发生时认为是某个数据包丢失,不必等待触发超时重发机制,直接进行重传,称为快速重传。之后拥塞窗口变为当前窗口的一半并进入拥塞控制阶段。
快速恢复
就是指发生快速重传时,之后拥塞窗口变为当前窗口的一半并进入拥塞控制阶段。而不必像超时发生时,重新进入慢启动。
UDP协议
它为应用层提供不可靠、无连接、基于数据报的服务。
其中基于数据报是指,每一个UDP数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出,否则数据将被截断。
参考内容
秀哥的校招笔记:https://interviewguide.cn/#/
游双老师《Linux高性能服务器编程》
谢希仁老师《计算机网络》第七版