特性 | TCP | UDP |
---|---|---|
面向连接 | 无连接 | |
可靠(确保数据完整、按顺序到达) | 不可靠(数据可能丢失、无序) | |
较慢(有连接和确认开销) | 较快(无连接和确认开销) | |
字节流(无边界) | 数据报(有明确边界) | |
文件传输、网页浏览、邮件传输等 | 实时通信、在线游戏、DNS 查询等 |
通俗的解释
- TCP:你打电话给朋友,先拨号建立连接,通话结束后挂断。通话过程中,如果对方没听到某句话,你可以重复说。
- UDP:你给朋友寄了一封明信片,不需要先打电话,直接寄出。明信片可能丢失,也可能迟到,但你不会知道。
下面给出一个基础的TCP通信代码案例
服务端代码
服务端代码的作用是监听客户端的连接请求,并与客户端进行通信。
完整代码
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Server
{
static void Main()
{
// 创建一个 TcpListener 对象,监听指定的 IP 地址和端口
TcpListener listener = new TcpListener(IPAddress.Any, 8080);
// 开始监听
listener.Start();
Console.WriteLine("Server started. Waiting for connection...");
try
{
// 等待客户端连接
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Client connected.");
// 获取网络流,用于读写数据
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("Received from client: " + message);
// 向客户端发送响应
byte[] response = Encoding.ASCII.GetBytes("Hello from server!");
stream.Write(response, 0, response.Length);
Console.WriteLine("Response sent to client.");
}
catch (Exception ex)
{
// 捕获异常并输出错误信息
Console.WriteLine("Error: " + ex.Message);
}
finally
{
// 关闭客户端连接和监听器
listener.Stop();
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
代码解析
-
创建
TcpListener
对象TcpListener listener = new TcpListener(IPAddress.Any, 8080);
TcpListener
是服务端的核心类,用于监听客户端的连接请求。IPAddress.Any
表示监听所有网络接口上的连接。8080
是监听的端口号。
-
开始监听
listener.Start(); Console.WriteLine("Server started. Waiting for connection...");
Start()
方法启动监听器,开始等待客户端连接。- 此时服务端会输出 “Server started. Waiting for connection…”。
-
等待客户端连接
TcpClient client = listener.AcceptTcpClient();
AcceptTcpClient()
方法会阻塞,直到有客户端连接到服务端。- 连接成功后,返回一个
TcpClient
对象,表示与客户端的连接。
-
获取网络流
NetworkStream stream = client.GetStream();
GetStream()
方法返回一个NetworkStream
对象,用于在连接中读写数据。
-
接收客户端消息
byte[] buffer = new byte[1024]; int bytesRead = stream.Read(buffer, 0, buffer.Length); string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Read()
方法从网络流中读取数据,返回实际读取的字节数。Encoding.ASCII.GetString()
将字节数组转换为字符串。- 服务端会输出 “Received from client: ” + 消息内容。
-
向客户端发送响应
byte[] response = Encoding.ASCII.GetBytes("Hello from server!"); stream.Write(response, 0, response.Length);
Encoding.ASCII.GetBytes()
将字符串转换为字节数组。Write()
方法将字节数组写入网络流,发送给客户端。
-
异常处理
catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); }
- 捕获异常并输出错误信息,方便调试。
-
关闭连接和监听器
finally { listener.Stop(); }
Stop()
方法停止监听器,关闭所有连接。
-
等待用户输入
Console.WriteLine("Press any key to exit..."); Console.ReadKey();
- 防止程序运行后立即退出,方便查看输出结果。
客户端代码
客户端代码的作用是连接到服务端,并与服务端进行通信。
完整代码
using System;
using System.Net.Sockets;
using System.Text;
class Client
{
static void Main()
{
// 创建一个 TcpClient 对象,用于连接到服务端
TcpClient client = new TcpClient();
try
{
// 连接到服务端
client.Connect("127.0.0.1", 8080);
Console.WriteLine("Connected to server.");
// 获取网络流,用于读写数据
NetworkStream stream = client.GetStream();
// 向服务端发送消息
byte[] message = Encoding.ASCII.GetBytes("Hello from client!");
stream.Write(message, 0, message.Length);
Console.WriteLine("Message sent to server.");
// 接收服务端的响应
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received from server: " + response);
}
catch (Exception ex)
{
// 捕获异常并输出错误信息
Console.WriteLine("Error: " + ex.Message);
}
finally
{
// 关闭客户端连接
client.Close();
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
代码解析
-
创建
TcpClient
对象TcpClient client = new TcpClient();
TcpClient
是客户端的核心类,用于连接到服务端。
-
连接到服务端
client.Connect("127.0.0.1", 8080);
Connect()
方法用于连接到指定的 IP 地址和端口。127.0.0.1
是本地回环地址,表示连接到本地服务端。8080
是服务端监听的端口号。
-
获取网络流
NetworkStream stream = client.GetStream();
GetStream()
方法返回一个NetworkStream
对象,用于在连接中读写数据。
-
向服务端发送消息
byte[] message = Encoding.ASCII.GetBytes("Hello from client!"); stream.Write(message, 0, message.Length);
Encoding.ASCII.GetBytes()
将字符串转换为字节数组。Write()
方法将字节数组写入网络流,发送给服务端。
-
接收服务端响应
byte[] buffer = new byte[1024]; int bytesRead = stream.Read(buffer, 0, buffer.Length); string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Read()
方法从网络流中读取数据,返回实际读取的字节数。Encoding.ASCII.GetString()
将字节数组转换为字符串。- 客户端会输出 “Received from server: ” + 响应内容。
-
异常处理
catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); }
- 捕获异常并输出错误信息,方便调试。
-
关闭连接
finally { client.Close(); }
Close()
方法关闭客户端连接。
-
等待用户输入
Console.WriteLine("Press any key to exit..."); Console.ReadKey();
- 防止程序运行后立即退出,方便查看输出结果。
运行步骤
-
先运行服务端代码:
- 服务端会输出 “Server started. Waiting for connection…”。
- 服务端开始监听客户端连接。
-
再运行客户端代码:
- 客户端会输出 “Connected to server.”。
- 客户端发送消息 “Hello from client!” 到服务端。
- 服务端接收消息并输出 “Received from client: Hello from client!”。
- 服务端发送响应 “Hello from server!”。
- 客户端接收响应并输出 “Received from server: Hello from server!”。
-
查看结果:
- 服务端和客户端的控制台窗口都会显示通信结果。
- 按任意键退出程序。
总结
通过以上详细解析,你可以快速理解服务端和客户端代码的逻辑。服务端负责监听连接并处理通信,客户端负责连接到服务端并发送/接收消息。掌握这些基础后,可以进一步学习更复杂的网络编程概念,如异步通信、多线程处理等。
来源链接:https://www.cnblogs.com/structurer/p/18827307
© 版权声明
本站所有资源来自于网络,仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您(转载者)自己承担!
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
THE END
暂无评论内容