TCP(传输控制协议)和 UDP(用户数据报协议)是两种在计算机网络中常用的传输层协议,它们在很多方面存在差异.
目录
连接特性
- TCP:面向连接的协议。在数据传输之前,需要在发送端和接收端之间建立一条连接,就像打电话一样,要先拨号接通,然后才能进行通话。连接建立过程通过三次握手来完成,确保双方都做好了数据传输的准备。数据传输完成后,还需要通过四次挥手来释放连接。
- UDP:无连接的协议。它不需要事先建立连接就可以直接发送数据,就像寄信一样,不需要与收件人先打招呼,直接把信寄出去就行。这种方式使得 UDP 的传输更加简单和快速,但也可能会导致数据的丢失或乱序。
可靠性
- TCP:提供可靠的传输服务。它通过序列号、确认应答、重传机制等保证数据能够准确无误地到达接收端。如果发送端发送的数据在一定时间内没有收到接收端的确认应答,就会认为数据丢失,然后重新发送该数据。此外,TCP 还能对收到的数据进行排序,确保数据按照发送的顺序进行交付。
- UDP:不保证数据传输的可靠性。UDP 只是简单地将数据报发送出去,不关心数据是否能够到达接收端,也不进行重传和排序等操作。因此,UDP 可能会出现数据丢失、重复或乱序的情况,但在某些对实时性要求较高的场景中,如视频直播、实时游戏等,少量的数据丢失对整体效果影响不大,UDP 就可以发挥其优势。
数据传输效率
- TCP:由于需要进行连接建立、确认应答、重传等操作,TCP 的开销相对较大,传输效率相对较低。尤其是在传输少量数据时,这些额外的开销可能会比较明显。
- UDP:没有连接建立和维护的过程,也不需要确认应答和重传,所以 UDP 的开销小,传输效率高。它能够快速地将数据发送出去,适合对实时性要求高、允许一定数据丢失的场景。
TCP连接(C#)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Program
{
// TCP 服务器示例
static void TcpServer()
{
try
{
//服务器连接请求
TcpListener server = new TcpListener(IPAddress.Any, 8888);
server.Start();
Console.WriteLine("TCP 服务器已启动,等待连接...");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("客户端已连接");
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("收到消息: " + message);
string response = "已收到消息";
byte[] data = Encoding.ASCII.GetBytes(response);
stream.Write(data, 0, data.Length);
client.Close();
server.Stop();
}
catch (Exception e)
{
Console.WriteLine("TCP 服务器出错: " + e.Message);
}
}
// TCP 客户端示例
static void TcpClient()
{
try
{
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 8888);
Console.WriteLine("已连接到 TCP 服务器");
//提供了一个用于在网络上发送和接收数据的流
NetworkStream stream = client.GetStream();
//发送
string message = "Hello, TCP Server!";
byte[] data = Encoding.ASCII.GetBytes(message);
stream.Write(data, 0, data.Length);
//接收
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("收到服务器响应: " + response);
client.Close();
}
catch (Exception e)
{
Console.WriteLine("TCP 客户端出错: " + e.Message);
}
}
UDP连接(C#)
服务器
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class UdpServer
{
static void Main()
{
try
{
// 创建 UdpClient 实例并绑定到指定端口
UdpClient server = new UdpClient(8888);
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("UDP 服务器已启动,等待数据...");
while (true)
{
// 接收客户端发送的数据
byte[] receiveBytes = server.Receive(ref remoteEndPoint);
string receiveMessage = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine($"收到来自 {remoteEndPoint} 的消息: {receiveMessage}");
// 发送响应消息给客户端
string sendMessage = "服务器已收到消息";
byte[] sendBytes = Encoding.ASCII.GetBytes(sendMessage);
server.Send(sendBytes, sendBytes.Length, remoteEndPoint);
}
}
catch (Exception e)
{
Console.WriteLine($"服务器出错: {e.Message}");
}
}
}
客户端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class UdpClientExample
{
static void Main()
{
try
{
// 创建 UdpClient 实例
UdpClient client = new UdpClient();
// 服务器的 IP 地址和端口
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, 8888);
// 要发送的消息
string sendMessage = "Hello, UDP Server!";
byte[] sendBytes = Encoding.ASCII.GetBytes(sendMessage);
// 发送数据到服务器
client.Send(sendBytes, sendBytes.Length, remoteEndPoint);
// 接收服务器的响应
IPEndPoint receiveEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receiveBytes = client.Receive(ref receiveEndPoint);
string receiveMessage = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine($"收到服务器响应: {receiveMessage}");
// 关闭客户端
client.Close();
}
catch (Exception e)
{
Console.WriteLine($"客户端出错: {e.Message}");
}
}
}
应用场景
- TCP:适用于对数据可靠性要求高的场景,如文件传输、电子邮件、远程登录、网页浏览等。例如,在下载文件时,我们希望文件能够完整无误地下载到本地,这就需要使用 TCP 协议来保证数据的准确性。
- UDP:适用于对实时性要求高、允许一定数据丢失的场景,如视频会议、在线游戏、实时监控、DNS(域名系统)查询等。以视频会议为例,为了保证视频和音频的流畅播放,即使有少量的数据丢失,也不会对整体的会议效果产生太大影响,此时使用 UDP 协议可以提高传输效率,减少延迟。