C# TCP/UDP
TCP
简介
TCP(Transmission Control Protocol,传输控制协议)是互联网协议套件中的核心协议之一,通常称为TCP/IP。它提供了可靠、有序和经过错误检查的数据流传输,在运行在IP网络上的主机之间的应用程序之间进行通信。TCP确保数据包以完整、顺序和无错误的方式传送。它通过使用确认和重传机制、流量控制和拥塞控制来实现这一点。
以下是TCP的一些关键特性:
面向连接,可靠的,字节流传输
- 可靠性:TCP保证数据包的传递。它通过使用确认和重传来实现这一点。当发送方传输数据时,它等待接收方的确认。如果在指定的时间内未收到确认,发送方将重新传输数据。
- 面向连接:TCP在数据交换开始之前,在两个端点(主机)之间建立连接。这种连接设置涉及到三次握手,双方在其中同意初始序列号和其他参数。
- 有序传递:TCP确保数据包按照发送顺序到达。如果数据包无序到达,TCP会在传递给应用程序之前重新排序它们。
- 流量控制:TCP实现了流量控制机制,以确保发送方不会用过多的数据压倒接收方。它使用滑动窗口技术来控制传输中的数据量。
- 拥塞控制:TCP通过减少发送数据的速率来应对网络拥塞。这有助于防止网络拥塞变得严重,从而保持网络稳定性。
TCP 四元组
TCP 四元组可以唯一的确定一个连接,四元组包括如下:
- 源地址
- 源端口
- 目的地址
- 目的端口
三次握手
三次握手是TCP连接建立过程中的重要步骤,用于确立客户端和服务器之间的通信连接。该过程包括以下三个步骤:
- 客户端发送同步(Synchronize)报文:客户端向服务器发送一个带有SYN标志的TCP报文,表示客户端请求建立连接,并选择一个初始序列号(ISN)。
- 服务器确认同步(SYN)报文并发送同步确认(SYN-ACK)报文:服务器收到客户端的SYN报文后,会回复一个带有SYN和Acknowledgment(ACK)标志的报文,表示接受客户端的连接请求,并确认客户端的初始序列号,同时也选择自己的初始序列号。
- 客户端发送确认(ACK)报文:客户端收到服务器的SYN-ACK报文后,会向服务器发送一个带有ACK标志的报文,表示已经收到服务器的确认,连接建立成功。
完成这三个步骤后,TCP连接就建立起来了,客户端和服务器之间可以开始进行数据传输。这种三次握手的设计可以确保双方都能够确认对方的能力,并且建立起来的连接是双向的可靠连接。
三次握手的作用
- 确保双方都能够通信:通过三次握手,客户端和服务器之间建立了双向的通信连接。在握手的过程中,客户端和服务器都能够确认对方的存在和可达性。这样可以避免像单向通信或者消息传输中的丢失、延迟等问题。
- 防止已失效的连接请求导致的资源浪费:如果在网络中存在延迟较大的连接请求,而服务端在超时之后收到了这个连接请求,它可能会以为这个连接请求是有效的并为其分配资源。然而,如果这个连接请求在网络中出现了问题,可能永远不会到达客户端。这种情况下,如果没有三次握手,服务器将会一直等待客户端的确认,导致资源的浪费。而通过三次握手,客户端和服务器都可以确认对方的确希望建立连接,从而避免了这种情况的发生。
判断客户端连接断开
在TCP连接中,可以通过以下几种方式来判断客户端连接是否已经断开:
- 超时检测:服务器可以设置一个超时阈值,在一段时间内如果没有收到客户端发送的数据,就认为连接已经断开。超时检测的时间间隔和超时阈值可以根据具体应用的需求来确定。
- 心跳机制:服务器可以定期向客户端发送心跳消息,客户端收到心跳消息后需要及时回复确认。如果服务器在一定时间内没有收到客户端的心跳回复,就可以认为连接已经断开。心跳机制可以有效地检测客户端的存活状态。
- 收到TCP断开连接的报文:TCP连接断开时,会触发断开连接的报文,如FIN报文。服务器可以通过检测是否收到这些报文来判断连接是否已经断开。
- 连接状态管理:服务器可以维护一个连接状态表,记录每个连接的状态和相关信息。通过监控连接状态表中的连接,可以及时发现连接的断开情况。
四次挥手
TCP连接的关闭是通过四次挥手来完成的,下面是四次挥手的过程:
- 客户端发送关闭请求(FIN):客户端向服务器发送一个带有 FIN 标志的TCP报文,表示客户端不再发送数据,但仍然可以接收数据。
- 服务器确认关闭请求(ACK):服务器收到客户端发送的FIN报文后,会向客户端发送一个确认ACK报文,表示已经收到了客户端的关闭请求。
- 服务器发送关闭请求(FIN):服务器在准备关闭连接之前,会继续向客户端发送数据,直到发送完毕。当服务器准备关闭连接时,会向客户端发送一个带有 FIN 标志的TCP报文,表示服务器不再发送数据。
- 客户端确认关闭请求(ACK):客户端收到服务器发送的FIN报文后,会向服务器发送一个确认ACK报文,表示已经收到了服务器的关闭请求。此时,客户端进入 TIME_WAIT 状态,等待一段时间后才彻底关闭连接。
通过这四次挥手的过程,客户端和服务器完成了连接的关闭,释放了连接所占用的资源,并确保数据的可靠传输。
滑动窗口
滑动窗口是 TCP 协议中的一种流量控制机制,用于调整发送方和接收方之间的数据传输速率,以避免网络拥塞和数据丢失。
在 TCP 中,发送方和接收方之间存在一个窗口,用于管理可接收的数据量。发送方可以发送窗口内的数据,而接收方则根据自身处理能力来调整窗口大小,以控制发送方的发送速率。
滑动窗口的基本原理是:发送方发送数据时,将数据包序列号和窗口大小信息发送给接收方,接收方根据自身能力确定可以接收的数据量,并将这个信息发送回发送方。发送方根据接收方发送回的信息调整窗口的大小,以控制发送速率。发送方只能发送接收方窗口内的数据,当接收方处理完数据后,窗口会向前滑动,发送方可以发送新的数据。
通过滑动窗口机制,TCP 可以根据网络和接收方的状况动态调整数据传输速率,保证了网络的稳定性和数据的可靠性。
拆包和粘包
TCP 拆包和粘包问题是在 TCP 协议中常见的一种现象,它们会影响到数据的正确接收和解析。这些问题的出现是由于 TCP 协议是面向流的传输协议,它只关心数据流的传输而不考虑应用层消息的边界。
- 拆包(Packet Splitting):拆包是指接收方接收到的数据包与发送方发送的数据包不完全对应的情况。例如,发送方在发送数据时,将一个逻辑上的消息分成了多个数据包进行发送,而接收方却只接收到了部分数据包,导致数据被拆分。这可能会使接收方无法正确解析数据。
- 粘包(Packet Pasting):粘包是指接收方接收到的多个数据包被合并成一个较大的数据包的情况。例如,发送方在发送数据时,将多个逻辑上的消息合并到了一个数据包中进行发送,而接收方却将这个数据包解析为多个消息,导致消息被粘在一起。这可能会使接收方无法准确分辨消息的边界。
解决 TCP 拆包和粘包问题的常用方法包括:
- 消息长度标识:在消息的开头加入一个固定长度的消息头,用于标识消息的长度。接收方首先读取消息头中的长度信息,然后根据这个长度来读取对应长度的数据,以正确解析消息。
- 分隔符:在消息的末尾添加一个特定的分隔符作为消息的结束标志。接收方根据分隔符来切分接收到的数据,从而将不同的消息分开。
- 消息序列号:为每个消息分配一个唯一的序列号,在消息中包含序列号信息。接收方根据序列号来确定消息的边界,从而正确解析消息。
UDP
UDP(User Datagram Protocol)是一种无连接的、不可靠的传输层协议,用于在网络上发送数据。
下面是UDP的一些关键特点和功能:
无连接,不可靠,数据报传输
- 无连接性:UDP是一种无连接的协议,这意味着在发送数据之前不需要建立连接。相比之下,TCP(Transmission Control Protocol)是一种面向连接的协议,它要求在数据传输之前先建立连接,然后再发送数据。
- 不可靠性:UDP不提供可靠性保证。它发送数据后不会对数据进行确认或者重传丢失的数据包。这意味着在UDP中,数据包的丢失、重复、乱序或损坏是可能发生的。这使得UDP适合于某些实时应用,如音频、视频传输,因为这些应用对数据的及时性要求高,而不太关心数据的准确性。
- 数据报形式:UDP通过数据报的形式发送数据。每个UDP数据包(数据报)都包含了源端口号、目标端口号、数据长度和校验和等信息。
- 轻量级:相比TCP,UDP协议是一种轻量级的协议,因为它不需要维护连接状态或执行拥塞控制。这使得UDP在某些情况下比TCP更加高效,特别是在网络带宽充足、延迟敏感的应用中。
- 广播和多播支持:UDP支持广播(向所有主机发送数据)和多播(向一组特定主机发送数据),这使得它在一些应用场景下非常有用,如视频流的传输。
- 适用性:UDP适用于一些特定的应用场景,如DNS查询、NTP时间同步、音频/视频流传输、在线游戏等。这些应用通常对数据的实时性要求较高,而且可以容忍一定程度的数据丢失或延迟。
总的来说,UDP是一种简单、高效但不可靠的协议,适用于某些对数据的实时性要求较高,而对数据的准确性要求较低的应用场景。
与TCP对比
UDP和TCP是两种常见的传输层协议,它们在功能和特性上有很多不同之处。以下是UDP和TCP之间的对比:
连接性:
- UDP:UDP是一种无连接的协议,发送数据之前不需要建立连接。
- TCP:TCP是一种面向连接的协议,发送数据之前需要先建立连接。
可靠性:
- UDP:UDP不提供可靠性保证,发送数据后不会进行确认或重传丢失的数据包。
- TCP:TCP提供可靠的数据传输,通过确认和重传机制确保数据的可靠性,以及保证数据的顺序性和完整性。
数据报形式:
- UDP:UDP以数据报的形式发送数据,每个数据报包含了源端口号、目标端口号、数据长度和校验和等信息。
- TCP:TCP以数据流的形式发送数据,数据被分割成小的数据段,并在传输过程中进行序号和确认号的管理。
拥塞控制:
- UDP:UDP不提供拥塞控制机制,发送方可以以任何速率发送数据。
- TCP:TCP提供拥塞控制机制,根据网络状况动态调整发送数据的速率,以避免网络拥塞。
适用性:
- UDP:UDP适用于一些对数据的实时性要求较高,但对数据的准确性要求较低的应用场景,如音频/视频传输、实时游戏等。
- TCP:TCP适用于对数据的可靠性和顺序性要求较高的应用场景,如网页浏览、文件传输、电子邮件等。
头部开销:
- UDP:UDP的头部较小,只包含必要的信息,因此具有较低的开销。
- TCP:TCP的头部较大,包含了更多的控制信息,因此具有较高的开销。
总的来说,UDP和TCP在传输方式、可靠性、连接性、适用性等方面有明显的区别,开发者在选择使用哪种协议时需要根据应用的需求来进行权衡。
OSI
OSI(Open Systems Interconnection,开放式系统互联)是一个定义了网络通信协议体系结构的参考模型,由国际标准化组织(ISO)制定。该模型将网络通信分为七个层次,每个层次都有特定的功能,上层通过下层提供的服务来实现通信。以下是OSI七层网络协议模型的每一层及其功能:
物理层(Physical Layer):
- 物理层负责传输原始比特流,定义了数据传输的物理介质、电气特性和接口标准。
- 主要任务是实现比特流的传输,而不考虑数据的含义或格式。
数据链路层(Data Link Layer):
- 数据链路层负责在相邻节点之间传送数据,通过物理层提供的服务进行逐帧传输,并检错。
- 定义了数据帧的格式、错误检测和纠正,以及介质访问控制。
网络层(Network Layer):
- 网络层负责实现数据的路由和转发,将数据从源主机传送到目标主机。
- 实现了逻辑地址的寻址和路由选择,例如IP地址,以及包括IP协议在内的路由协议。
传输层(Transport Layer):
- 传输层提供端到端的数据传输服务,负责数据的可靠传输和数据流的控制。
- 主要协议有TCP(面向连接)和UDP(无连接),TCP提供可靠的数据传输,UDP提供不可靠的数据传输。
会话层(Session Layer):
- 会话层负责建立、管理和终止会话(会话是两个应用程序之间的通信会话),提供数据交换的方式。
- 实现了会话的建立、维护和终止,以及数据的同步和检查点的管理。
表示层(Presentation Layer):
- 表示层负责数据的格式化、加密和压缩,使得不同系统的数据能够相互识别和交换。
- 实现了数据的格式转换、加密解密、压缩解压缩等操作,以确保数据的可移植性和安全性。
应用层(Application Layer):
- 应用层提供用户与网络服务之间的接口,为用户提供各种网络服务和应用程序。
- 包括各种网络应用协议,如HTTP、FTP、SMTP等,以及与用户交互的各种应用程序接口。
OSI七层模型提供了一个标准化的网络通信框架,有助于理解和设计网络系统,但在实际应用中,常用的网络协议栈如TCP/IP协议栈并不完全符合OSI模型,但其概念和原理仍然是适用的。