C Sharp TCP 编程
外观
C# TCP编程[编辑 | 编辑源代码]
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在C#中,TCP编程通过System.Net.Sockets命名空间中的TcpListener和TcpClient类实现,用于构建客户端-服务器应用程序。
基本概念[编辑 | 编辑源代码]
TCP协议提供以下关键特性:
- 面向连接:通信前需建立连接(三次握手)
- 可靠传输:通过确认机制和重传保证数据完整
- 有序交付:数据按发送顺序到达
- 流量控制:防止发送方淹没接收方
基础TCP服务器实现[编辑 | 编辑源代码]
以下是简单TCP服务器示例:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class TcpServer
{
static void Main()
{
// 1. 创建监听器
TcpListener server = new TcpListener(IPAddress.Any, 8888);
server.Start();
Console.WriteLine("服务器已启动,等待连接...");
// 2. 接受客户端连接
TcpClient client = server.AcceptTcpClient();
Console.WriteLine($"客户端已连接: {client.Client.RemoteEndPoint}");
// 3. 获取网络流
NetworkStream stream = client.GetStream();
// 4. 读取客户端数据
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"收到数据: {data}");
// 5. 发送响应
string response = "消息已接收";
byte[] responseData = Encoding.UTF8.GetBytes(response);
stream.Write(responseData, 0, responseData.Length);
// 6. 关闭连接
client.Close();
server.Stop();
}
}
基础TCP客户端实现[编辑 | 编辑源代码]
对应服务器的客户端代码:
using System;
using System.Net.Sockets;
using System.Text;
class TcpClientExample
{
static void Main()
{
// 1. 创建客户端并连接服务器
TcpClient client = new TcpClient("127.0.0.1", 8888);
Console.WriteLine("已连接到服务器");
// 2. 获取网络流
NetworkStream stream = client.GetStream();
// 3. 发送数据
string message = "Hello, Server!";
byte[] data = Encoding.UTF8.GetBytes(message);
stream.Write(data, 0, data.Length);
Console.WriteLine($"已发送: {message}");
// 4. 接收响应
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"服务器响应: {response}");
// 5. 关闭连接
client.Close();
}
}
异步TCP编程[编辑 | 编辑源代码]
对于需要处理多个连接的服务器,应使用异步方法:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
class AsyncTcpServer
{
static async Task Main()
{
TcpListener server = new TcpListener(IPAddress.Any, 8888);
server.Start();
Console.WriteLine("异步服务器已启动");
while (true)
{
TcpClient client = await server.AcceptTcpClientAsync();
_ = HandleClientAsync(client); // 不等待以接受新连接
}
}
static async Task HandleClientAsync(TcpClient client)
{
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
byte[] buffer = new byte[1024];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
string request = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"收到: {request}");
string response = $"ECHO: {request}";
byte[] responseData = Encoding.UTF8.GetBytes(response);
await stream.WriteAsync(responseData, 0, responseData.Length);
}
}
catch (Exception ex)
{
Console.WriteLine($"客户端处理错误: {ex.Message}");
}
}
}
实际应用案例[编辑 | 编辑源代码]
聊天应用程序是TCP编程的典型应用:
1. 服务器角色:
* 维护所有连接的客户端列表 * 接收消息并广播给所有客户端 * 处理客户端连接/断开事件
2. 客户端角色:
* 连接服务器 * 发送用户输入的消息 * 显示来自其他客户端的消息
高级主题[编辑 | 编辑源代码]
协议设计[编辑 | 编辑源代码]
TCP是字节流协议,需要应用层协议解决消息边界问题:
- 固定长度:每条消息固定大小
- 分隔符:使用特殊字符(如\\n)分隔消息
- 长度前缀:消息前添加长度字段
性能优化[编辑 | 编辑源代码]
- 使用BufferManager减少内存分配
- 实现对象池重用TcpClient实例
- 使用SocketAsyncEventArgs进行高性能socket操作
安全考虑[编辑 | 编辑源代码]
- 使用SSLStream加密通信
- 实现身份验证机制
- 防范DoS攻击(连接限制、超时设置)
常见问题[编辑 | 编辑源代码]
- Q: 如何处理连接断开?
A: 捕获SocketException和IOException,错误代码10054表示连接重置
- Q: 为什么Read()会阻塞?
A: 默认是阻塞模式,使用异步方法或设置ReceiveTimeout
- Q: 如何测试TCP应用?
A: 使用telnet或nc(netcat)作为临时客户端
数学基础[编辑 | 编辑源代码]
TCP拥塞控制使用以下算法:
其中CWND表示拥塞窗口大小,RTT是往返时间。