Python栈与队列实现:从list、deque到手动链表,性能与应用全解析
2026/8/4 5:57:51
TCP 通信分为服务端与客户端:
窗体控件:
button1:连接服务器按钮button2:发送数据按钮textBox1:输入待发送文本label1:状态提示文本 全局变量:Socket client;客户端套接字对象private async void button1_Click(object sender, EventArgs e) { try { //1. 创建TCP客户端Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //2. 构造服务端终端(服务端IP + 端口) IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("192.168.219.30"), 63323); //3. 异步连接服务端 await client.ConnectAsync(endPoint); label1.Text = "连接成功"; button1.Enabled = false; button2.Enabled = true; } catch (Exception) { MessageBox.Show("服务器未打开"); return; } }AddressFamily.InterNetwork(IPv4)、SocketType.Stream、ProtocolType.Tcp⚠️ IP 地址需要修改为服务端电脑实际 IP,端口号必须一致(63323)
client.Connect(endPoint):同步连接,阻塞 UI 线程,界面会卡死await client.ConnectAsync(endPoint):异步连接,搭配 async void,不卡住窗体,推荐写法private void button2_Click(object sender, EventArgs e) { // 校验1:判断客户端是否有效、是否处于连接状态 if (client == null || !client.Connected) { MessageBox.Show("还没连接到服务器,请先连接服务器"); return; } // 校验2:判断发送内容不能为空 if (string.IsNullOrEmpty(textBox1.Text)) { MessageBox.Show("发送数据不能为空"); return; } try { //字符串 → UTF8字节数组 byte[] data = Encoding.UTF8.GetBytes(textBox1.Text); client.Send(data); label1.Text = "发送成功"; } catch (Exception) { label1.Text = "发送失败"; //连接断开,释放资源 if (client != null) { if (client.Connected) client.Shutdown(SocketShutdown.Both); client.Close(); client.Dispose(); } button1.Enabled = true; button2.Enabled = false; } }Encoding.UTF8.GetBytes()→ byte [] 服务端接收后反向转换:byte [] →Encoding.UTF8.GetString()→ 字符串client.Send(byte[]):向服务端发送字节数据client.Shutdown(SocketShutdown.Both); //关闭读写通道 client.Close(); //关闭套接字 client.Dispose(); //释放内存资源SocketShutdown.Both:同时禁止读取和写入。 回收完成后恢复按钮状态,允许用户重新连接。
表格
| 功能 | TCP 服务端 | TCP 客户端 |
|---|---|---|
| Bind 绑定 | ✅ 需要绑定本机 IP 端口 | ❌ 不需要 Bind |
| Listen 监听 | ✅ 需要 | ❌ 不需要 |
| Accept 接收连接 | ✅ 需要循环等待客户端 | ❌ 不需要 |
| Connect 连接 | ❌ 不需要 | ✅ 主动 Connect/ConnectAsync |
| Socket 作用 | server 套接字专门等待连接,通信交给 client 套接字 | 唯一 client 套接字,同时负责收发 |
192.168.219.30,优化方案:使用文本框让用户手动输入服务端 IP。client.Send()是同步方法,大数据发送时可能短暂卡顿界面;高级写法使用SendAsync。表格
| 方法 | 作用 |
|---|---|
Socket.ConnectAsync(IPEndPoint) | 异步主动连接服务端(推荐) |
Socket.Connect(IPEndPoint) | 同步连接,阻塞界面 |
Socket.Send(byte[]) | 发送字节数据到远端 |
Socket.Shutdown(SocketShutdown.Both) | 关闭套接字读写通道 |
Socket.Close() | 关闭套接字 |
Socket.Dispose() | 释放套接字占用系统资源 |
client.Connected | 判断套接字当前是否处于连接状态 |
ipconfig查询服务端本机 IPv4 地址Async异步方法,避免 UI 界面卡死。public partial class Form1 : Form { public Form1() { InitializeComponent(); } Socket client; //开始链结 private async void button1_Click(object sender, EventArgs e) { try { //1.创建客户端实例 client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //2.创建终端 IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("192.168.219.30"),63323); //3.开始连接服务器 //client.Connect(endPoint);//同步链接 await client.ConnectAsync(endPoint);//等待异步连接结果 label1.Text = "连接成功"; button1.Enabled = false; button2.Enabled = true; } catch(Exception) { MessageBox.Show("服务器未打开"); return; } } //发送 private void button2_Click(object sender, EventArgs e) { if (client == null || !client.Connected) { MessageBox.Show("还没连接到服务器,请先连接服务器"); return; } if (string.IsNullOrEmpty(textBox1.Text)) { MessageBox.Show("发送数据不能为空"); return; } //发送数据 try { byte[] data = Encoding.UTF8.GetBytes(textBox1.Text); client.Send(data);//发送数据 label1.Text = "发送成功"; } catch (Exception) { label1.Text = "发送失败"; if (client != null) //客户端不等于空 { if (client.Connected) client.Shutdown(SocketShutdown.Both);//客户端还处于连接状态 关闭连接 client.Close();//关闭客户端 client.Dispose();//释放资源 } button1.Enabled = true; button2.Enabled = false; } } }