云计算百科
云计算领域专业知识百科平台

简单TCP服务器与客户端实现(C# WinForm)

本文将展示一个基于C# WinForm的TCP通信实例,包含服务端和客户端的完整实现代码,可用于局域网内的简易消息通信。

一、核心功能

客户端:连接服务器、发送消息、接收消息 服务器:监听端口、管理多客户端、消息广播 技术栈:`TcpClient`/`TcpListener` + `NetworkStream` + 多线程处

二、客户端实现代码解析  

using System.Net; using System.Net.Sockets; // …其他命名空间…

namespace WindowsFormsTcpClient {     public partial class FormClient : Form     {         private TcpClient tcpClient = new TcpClient();         private NetworkStream stream;

        // 连接服务器按钮         private void buttonConnectServer_Click(object sender, EventArgs e)         {             try             {                 tcpClient.Connect(IPAddress.Parse("10.92.207.45"), 12138);                 stream = tcpClient.GetStream();                                  // 启动接收线程                 Task.Run(() => {                     byte[] data = new byte[1024];                     while (true)                     {                         int count = stream.Read(data, 0, 1024);                         if (count == 0) break;  // 连接断开                                                  string message = Encoding.Default.GetString(data, 0, count) + "\\r\\n";                         this.Invoke(() => {                             textBoxReceive.Text += message;  // 更新UI                         });                     }                 });                 MessageBox.Show("连接成功!");             }             catch (Exception ex)             {                 MessageBox.Show($"连接失败:{ex.Message}");             }         }

        // 发送消息按钮         private void buttonSend_Click(object sender, EventArgs e)         {             if (stream != null)             {                 String sendString = this.textBoxSend.Text;                 byte[] data = Encoding.Default.GetBytes(sendString);                 stream.Write(data, 0, data.Length);             }         }     } }

(客户端部分代码示例)

关键点说明: 1. 使用`Task.Run`创建独立接收线程,避免UI阻塞 2. `stream.Read`会阻塞线程直到收到数据 3. `this.Invoke`确保跨线程安全更新UI 4. 固定IP和端口(12138)需根据实际环境修改

三、服务端实现代码解析

using System.Net; using System.Net.Sockets; // …其他命名空间…

namespace WindowsFormsTcpServer {     public partial class FormServer : Form     {         private TcpListener TcpListener;         private Dictionary<String, TcpClient> clients = new Dictionary<string, TcpClient>();

        // 启动服务器按钮         private void buttonStartServer_Click(object sender, EventArgs e)         {             try             {                 TcpListener = new TcpListener(IPAddress.Parse("10.92.207.45"), 12138);                 TcpListener.Start();                                  // 监听客户端连接                 new Task(() => {                     while (true)                     {                         TcpClient client = TcpListener.AcceptTcpClient();                         IPEndPoint endpoint = (IPEndPoint)client.Client.RemoteEndPoint;                         String ip = endpoint.Address.ToString();                                                  clients.Add(ip, client);  // 存储客户端

                        // 为每个客户端创建接收线程                         new Task(() => {                             NetworkStream stream = client.GetStream();                             byte[] data = new byte[1024];                             while (true)                             {                                 int count = stream.Read(data, 0, 1024);                                 String message = Encoding.Default.GetString(data, 0, count) + "\\r\\n";                                 this.Invoke(() => {                                     textBoxReceive.Text += $"[{ip}] {message}";  // 显示消息来源                                 });                             }                         }).Start();                     }                 }).Start();                                  MessageBox.Show("服务器已启动");             }             catch (Exception ex) { /* 错误处理 */ }         }

        // 广播消息按钮         private void buttonSend_Click(object sender, EventArgs e)         {             foreach (var client in clients.Values)             {                 NetworkStream stream = client.GetStream();                 String sendString = this.textBoxSend.Text;                 byte[] data = Encoding.Default.GetBytes(sendString);                 stream.Write(data, 0, data.Length);  // 向所有客户端发送             }         }     } }

(服务端部分代码示例)

关键点说明: 1. 使用`Dictionary`存储所有连接的客户端 2. `AcceptTcpClient()`阻塞等待新连接 3. 为每个客户端创建独立接收线程 4. 广播消息遍历所有客户端

四、代码优化建议

 1. 连接健壮性改进 // 客户端增加断开检测 if (count == 0) {     this.Invoke(() => MessageBox.Show("连接已断开"));     break; }

// 服务端增加异常处理 try {     int count = stream.Read(data, 0, 1024);     // … } catch (IOException) {     clients.Remove(ip);  // 移除断开连接     break; }

 2. 资源释放 // 重写窗体关闭事件 protected override void OnFormClosing(FormClosingEventArgs e) {     stream?.Close();     tcpClient?.Close();     base.OnFormClosing(e); }

3. 配置解耦 建议将IP和端口移到配置文件:

//HTIM// <appSettings>     <add key="ServerIP" value="10.92.207.45"/>     <add key="Port" value="12138"/> </appSettings>

(运行示例)

五、使用注意事项

1. 防火墙设置:需在防火墙开放12138端口 2. IP地址:服务端IP需改为实际本机IP 3. 连接顺序:先启动服务端再启动客户端 4. 广播限制:当前版本未做消息分包处理,长消息可能截断

六、完整项目结构

TCP通信示例  WindowsFormsTcpServer  FormServer.cs     // 服务端主窗体 app.config        // 配置文件 WindowsFormsTcpClient FormClient.cs     // 客户端主窗体 ```

通过这个基础框架,您可以扩展实现: 用户认证系统 私聊功能(通过IP识别) 文件传输 心跳检测机制

欢迎在评论区交流实现中遇到的问题或分享改进方案!

赞(0)
未经允许不得转载:网硕互联帮助中心 » 简单TCP服务器与客户端实现(C# WinForm)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!