一、TCP 基础理论知识点 + 对应代码
1.1 TCP 四大核心特点(背诵知识点)
面向连接:通信前三次握手建立连接
流式无边界传输:数据连续流传输,需要固定缓冲区接收
可靠传输:自带确认重传,无丢包
全双工:两端可同时收发数据
1.2 Socket 核心构造参数(知识点 + 对应代码)
知识点:TCP 套接字固定三参数:IPv4地址族、流式套接字、TCP协议
// 对应考点:TCP协议参数固定写法 new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);参数释义:
AddressFamily.InterNetwork:使用 IPv4 协议SocketType.Stream:TCP 流式传输ProtocolType.Tcp:指定 TCP 通信协议
二、服务端五步法
- new Socket()创建服务端监听对象
- Bind()绑定本机 IP + 端口
- Listen(100)开启端口监听
- Accept()阻塞接收客户端连接
- Receive()循环接收客户端数据
步骤1:创建服务端Socket对象(知识点+代码)
知识点:服务端全局声明Socket对象,用于监听客户端连接
// 服务端核心监听对象 Socket server = null;步骤2:自动获取本机IPv4地址(知识点+代码)
知识点:自动遍历本机所有网卡,筛选IPv4地址,适配不同电脑
string ipStr = ""; int port = 63323; // 高位端口,避免冲突 // 获取本机所有网络地址 IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress item in host.AddressList) { // 只保留IPv4 if (item.AddressFamily == AddressFamily.InterNetwork) { ipStr = item.ToString(); } }步骤3:绑定IP和端口(Bind)(知识点+代码)
知识点:将Socket与本机IP、端口绑定,对外开放服务端口
IPAddress address = IPAddress.Parse(ipStr); IPEndPoint endPoint = new IPEndPoint(address, port); server.Bind(endPoint); // 绑定端口核心方法步骤4:开启端口监听(Listen)(知识点+代码)
知识点:Listen(最大挂起连接数),开启端口监听,等待客户端接入
server.Listen(100); // 允许最多100个排队连接步骤5:异步监听多客户端连接(Accept)(知识点+代码)
知识点:双层Task嵌套,外层循环接收新客户端,实现多客户端通信
CancellationTokenSource cts; public void AcceptDataMul() { cts = new CancellationTokenSource(); Task.Run(() => { while (!cts.IsCancellationRequested) { // 阻塞接收客户端连接 Socket client = server.Accept(); } }, cts.Token); }步骤6:单客户端独立接收数据(知识点+代码)
知识点:每个客户端独立子线程接收数据,互不干扰;修复TCP粘包BUG
// 固定缓冲区,解决TCP流式无边界粘包问题 byte[] buffer = new byte[1024 * 10]; int length = client.Receive(buffer); if (length <= 0) break; // 客户端离线断开步骤7:跨线程UI更新(必考知识点+代码)
知识点:子线程禁止直接操作UI,必须使用Invoke回调主线程
string recStr = Encoding.UTF8.GetString(buffer, 0, length); Invoke(new Action(() => { richTextBox1.AppendText(recStr + Environment.NewLine); }));步骤8:客户端断开资源释放(知识点+代码)
知识点:捕获异常,主动关闭套接字,避免端口占用、内存泄漏
catch (Exception) { client.Close(); client.Dispose(); break; }服务端关键考点
- 自动筛选本机IPv4地址,排除 IPv6
- 多客户端原理:双层 Task 外层:循环 Accept 接客户端 内层:每个客户端独立线程收数据
- 跨线程 UI 报错解决:子线程更新控件必须用
Invoke - TCP 粘包修复:固定缓冲区
new byte[1024*10] - 线程安全:
CancellationTokenSource安全终止后台任务
四、客户端四步法
- 创建客户端 Socket
- 指定服务端IPEndPoint(IP + 端口)
- ConnectAsync 异步连接(不卡死 UI)
- Send()发送数据
步骤1:声明客户端Socket(知识点+代码)
知识点:单客户端通信,仅需一个Socket对象
Socket client;步骤2:创建客户端Socket(知识点+代码)
知识点:客户端参数与服务端一致,保证通信协议匹配
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);步骤3:配置服务端终端节点(知识点+代码)
知识点:客户端必须指定服务端精准IP+端口才能连接
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.219.12"), 63323);步骤4:异步连接服务端(核心考点+代码)
知识点:ConnectAsync异步连接,不阻塞UI主线程,避免界面卡死
await client.ConnectAsync(endpoint);步骤5:连接成功UI状态联动(知识点+代码)
知识点:禁止重复连接,按钮状态互斥,优化交互逻辑
label1.Text = "连接成功"; button1.Enabled = false; button2.Enabled = true;步骤6:连接失败容错处理(知识点+代码)
知识点:捕获服务端未开启、IP错误、端口错误异常
label1.Text = "连接成功"; button1.Enabled = false; button2.Enabled = true;五、客户端发送数据 知识点逐段对应
5.1 连接状态校验(防报错知识点+代码)
知识点:发送数据前必须判断Socket非空、处于连接状态
if (client == null || !client.Connected) { MessageBox.Show("还没连接到服务器,请先连接服务器"); return; }5.2 空数据校验(规范考点+代码)
知识点:禁止发送空数据,无效通信拦截
if (string.IsNullOrEmpty(textBox1.Text)) { MessageBox.Show("发送数据不能为空"); return; }5.3 UTF8编码转换(乱码解决考点+代码)
知识点:收发统一UTF8编码,彻底解决中文乱码
byte[] data = Encoding.UTF8.GetBytes(textBox1.Text); client.Send(data); label1.Text = "发送成功";5.4 异常完整资源释放(高频考点+代码)
知识点:三段式资源释放:关闭通道→关闭连接→释放资源
if (client != null) { if (client.Connected) client.Shutdown(SocketShutdown.Both); // 关闭读写通道 client.Close(); // 关闭连接 client.Dispose(); // 释放资源 } // 重置按钮状态 button1.Enabled = true; button2.Enabled = false;客户端安全规范
- 发送前判空:
client!=null && client.Connected - 禁止发送空字符串
- 统一UTF8 编码防止中文乱码
- 异常三步释放资源:
Shutdown→Close→Dispose
五、高频易错点
5.1 线程安全控制(CancellationToken)
知识点:使用取消令牌安全终止异步线程,杜绝后台线程残留
CancellationTokenSource cts2 = new CancellationTokenSource(); Task.Run(() => {}, cts2.Token);5.2 修复TCP原生粘包BUG
知识点:废弃 client.Available 动态缓冲区,使用固定缓冲区循环接收
// 正确写法 byte[] buffer = new byte[1024 * 10]; int length = client.Receive(buffer); // 错误原生写法(已废弃) // byte[] buffer = new byte[client.Available];- 禁止子线程直接操作 UI,必须 Invoke
- TCP 无数据边界,禁用 client.Available
- 端口建议高位(>10000)防冲突
- 客户端 IP 必须与服务端本机 IPv4 一致
- 必须异步连接,同步 Connect 会卡死界面
- 通信完毕必须释放资源,否则端口占用、内存泄漏