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

基于SunnyUI的WinForm TCP服务器实现

基于SunnyUI的WinForm TCP服务器实现

目录

  • 一、项目概述
  • 二、项目界面设计
  • 三、关键代码解析
  • 四、项目亮点
  • 五、使用说明
  • 六、总结
  • 七、完整代码

一、项目概述

本期末作业实现了一个基于SunnyUI界面的TCP服务器应用程序,主要功能包括:

  • 启动TCP服务器监听指定端口
  • 接收多个客户端连接
  • 显示客户端发送的消息
  • 向所有连接的客户端广播消息

该项目展示了WinForm应用程序开发、TCP网络编程、多线程处理以及SunnyUI界面库的应用。

二、项目界面设计

项目使用了SunnyUI控件库构建了美观的界面:

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fvia.placeholder.com%2F600x400%3Ftext%3DTCP%2BServer%2BInterface&pos_id=img-x6LB9fC6-1750245738944)

界面主要包含以下元素:

  • 接收数据文本框:显示来自客户端的消息
  • 发送数据文本框:输入要发送给客户端的消息
  • "启动服务器"按钮:开始监听客户端连接
  • "发送数据"按钮:向所有客户端广播消息

三、关键代码解析

1. 服务器启动逻辑

private void uibuttonStartServer_Click_1(object sender, EventArgs e)
{
try
{
// 创建TCP监听器,监听IP和端口
tcpListener = new TcpListener(IPAddress.Parse("192.168.209.171"), 6666);
tcpListener.Start();
UIMessageBox.Show("启动服务器成功");

// 在新任务中处理客户端连接
new Task(() =>
{
while (true)
{
// 接受客户端连接
TcpClient client = tcpListener.AcceptTcpClient();
// 获取客户端IP
IPEndPoint iPEndPoint = (IPEndPoint)(client.Client.RemoteEndPoint);
String ip = iPEndPoint.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";

// 使用Invoke更新UI
this.Invoke(new Action(() =>
{
this.uitextBoxReceive.Text += message;
}));
}
}).Start();
}
}).Start();
}
catch (Exception e2)
{
UIMessageBox.Show("启动服务器失败:" + e2.Message);
}
}

2. 消息发送功能

private void uibuttonSend_Click(object sender, EventArgs e)
{
// 遍历所有连接的客户端
foreach (var client in this.clients.Values)
{
NetworkStream stream = client.GetStream();
String sendString = this.uitextBoxSend.Text;
// 将文本转换为字节数组
byte[] data = Encoding.Default.GetBytes(sendString);
// 发送数据
stream.Write(data, 0, data.Length);
}
}

3. 客户端管理

// 存储客户端连接的字典
private Dictionary<String, TcpClient> clients;

public FormServer()
{
InitializeComponent();
// 初始化客户端字典
clients = new Dictionary<string, TcpClient>();
}

四、项目亮点

  • 多线程处理:使用Task实现异步处理客户端连接和消息接收
  • 线程安全:使用Invoke方法安全更新UI组件
  • 客户端管理:使用字典存储客户端连接,便于管理
  • 优雅的UI:采用SunnyUI控件库,界面美观现代
  • 健壮性:异常处理确保服务器稳定运行
  • 五、使用说明

  • 编译并运行服务器程序
  • 点击"启动服务器"按钮
  • 使用TCP客户端工具(如NetAssist)连接服务器
  • 在接收框中查看客户端发送的消息
  • 在发送框中输入消息,点击"发送数据"广播给所有客户端
  • 六、总结

    本期末作业实现了一个功能完整的TCP服务器,涵盖了WinForm开发、网络编程、多线程处理等关键技术点。通过使用SunnyUI控件库,界面简洁美观且功能完善。项目展示了良好的编程实践,包括异常处理、资源管理和线程安全。

    在实际应用中,可以进一步扩展以下功能:

    • 添加客户端列表显示
    • 实现私聊功能
    • 增加消息加密
    • 添加用户认证机制
    • 实现消息历史记录

    #mermaid-svg-aJQiRexBQBShYVhe {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-aJQiRexBQBShYVhe .error-icon{fill:#552222;}#mermaid-svg-aJQiRexBQBShYVhe .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aJQiRexBQBShYVhe .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-aJQiRexBQBShYVhe .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aJQiRexBQBShYVhe .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aJQiRexBQBShYVhe .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aJQiRexBQBShYVhe .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aJQiRexBQBShYVhe .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aJQiRexBQBShYVhe .marker.cross{stroke:#333333;}#mermaid-svg-aJQiRexBQBShYVhe svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aJQiRexBQBShYVhe .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-aJQiRexBQBShYVhe .cluster-label text{fill:#333;}#mermaid-svg-aJQiRexBQBShYVhe .cluster-label span{color:#333;}#mermaid-svg-aJQiRexBQBShYVhe .label text,#mermaid-svg-aJQiRexBQBShYVhe span{fill:#333;color:#333;}#mermaid-svg-aJQiRexBQBShYVhe .node rect,#mermaid-svg-aJQiRexBQBShYVhe .node circle,#mermaid-svg-aJQiRexBQBShYVhe .node ellipse,#mermaid-svg-aJQiRexBQBShYVhe .node polygon,#mermaid-svg-aJQiRexBQBShYVhe .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aJQiRexBQBShYVhe .node .label{text-align:center;}#mermaid-svg-aJQiRexBQBShYVhe .node.clickable{cursor:pointer;}#mermaid-svg-aJQiRexBQBShYVhe .arrowheadPath{fill:#333333;}#mermaid-svg-aJQiRexBQBShYVhe .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aJQiRexBQBShYVhe .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aJQiRexBQBShYVhe .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-aJQiRexBQBShYVhe .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-aJQiRexBQBShYVhe .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aJQiRexBQBShYVhe .cluster text{fill:#333;}#mermaid-svg-aJQiRexBQBShYVhe .cluster span{color:#333;}#mermaid-svg-aJQiRexBQBShYVhe div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aJQiRexBQBShYVhe :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    启动服务器

    监听端口6666

    接受客户端连接

    存储客户端信息

    接收客户端消息

    显示在接收框

    发送消息

    遍历所有客户端

    发送消息

    七、完整代码

    Program.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace WindowsFormsTcpServer
    {
    static class Program
    {
    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main()
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new FormServer());
    }
    }
    }

    FormServer.cs

    using Sunny.UI;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace WindowsFormsTcpServer
    {
    public partial class FormServer : UIForm
    {
    private TcpListener tcpListener;
    private Dictionary<String, TcpClient> clients;

    public FormServer()
    {
    InitializeComponent();
    clients = new Dictionary<string, TcpClient>();
    }

    private void FormServer_Load(object sender, EventArgs e)
    {
    // 初始化代码
    }

    private void uibuttonSend_Click(object sender, EventArgs e)
    {
    foreach (var client in this.clients.Values)
    {
    NetworkStream stream = client.GetStream();
    String sendSring = this.uitextBoxSend.Text;
    byte[] data = Encoding.Default.GetBytes(sendSring);
    stream.Write(data, 0, data.Length);
    }
    }

    private void uibuttonStartServer_Click_1(object sender, EventArgs e)
    {
    try
    {
    tcpListener = new TcpListener(IPAddress.Parse("192.168.209.171"), 6666);
    tcpListener.Start();
    UIMessageBox.Show("启动服务器成功");

    }
    catch (Exception e2)
    {
    UIMessageBox.Show("启动服务器失败:" + e2.Message);
    return;
    }

    new Task(
    () =>
    {
    while (true)
    {
    TcpClient client = tcpListener.AcceptTcpClient();
    IPEndPoint iPEndPoint = (IPEndPoint)(client.Client.RemoteEndPoint);
    String ip = iPEndPoint.Address.ToString();
    clients.Add(ip, client);
    Thread.Sleep(1000);

    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(new Action(() =>
    {
    this.uitextBoxReceive.Text += message;
    }));
    }
    }).Start();
    }
    }).Start();
    }
    }
    }

    FormServer.Designer.cs

    namespace WindowsFormsTcpServer
    {
    partial class FormServer
    {
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
    protected override void Dispose(bool disposing)
    {
    if (disposing && (components != null))
    {
    components.Dispose();
    }
    base.Dispose(disposing);
    }

    #region Windows 窗体设计器生成的代码

    /// <summary>
    /// 设计器支持所需的方法 – 不要修改
    /// 使用代码编辑器修改此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    this.uiSmoothLabel2 = new Sunny.UI.UISmoothLabel();
    this.uiSmoothLabel1 = new Sunny.UI.UISmoothLabel();
    this.uitextBoxSend = new Sunny.UI.UITextBox();
    this.uibuttonStartServer = new Sunny.UI.UIHeaderButton();
    this.uibuttonSend = new Sunny.UI.UIHeaderButton();
    this.uitextBoxReceive = new Sunny.UI.UITextBox();
    this.SuspendLayout();
    //
    // uiSmoothLabel2
    //
    this.uiSmoothLabel2.Font = new System.Drawing.Font("华文楷体", 16.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    this.uiSmoothLabel2.ForeColor = System.Drawing.Color.Transparent;
    this.uiSmoothLabel2.Location = new System.Drawing.Point(127, 54);
    this.uiSmoothLabel2.Name = "uiSmoothLabel2";
    this.uiSmoothLabel2.Size = new System.Drawing.Size(175, 30);
    this.uiSmoothLabel2.TabIndex = 55;
    this.uiSmoothLabel2.Text = "接收到的数据";
    //
    // uiSmoothLabel1
    //
    this.uiSmoothLabel1.Font = new System.Drawing.Font("华文楷体", 16.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    this.uiSmoothLabel1.ForeColor = System.Drawing.Color.Transparent;
    this.uiSmoothLabel1.Location = new System.Drawing.Point(126, 330);
    this.uiSmoothLabel1.Name = "uiSmoothLabel1";
    this.uiSmoothLabel1.Size = new System.Drawing.Size(175, 30);
    this.uiSmoothLabel1.TabIndex = 56;
    this.uiSmoothLabel1.Text = "要发送的数据";
    //
    // uitextBoxSend
    //
    this.uitextBoxSend.ButtonWidth = 100;
    this.uitextBoxSend.Cursor = System.Windows.Forms.Cursors.IBeam;
    this.uitextBoxSend.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    this.uitextBoxSend.Location = new System.Drawing.Point(132, 365);
    this.uitextBoxSend.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
    this.uitextBoxSend.MinimumSize = new System.Drawing.Size(1, 1);
    this.uitextBoxSend.Multiline = true;
    this.uitextBoxSend.Name = "uitextBoxSend";
    this.uitextBoxSend.Padding = new System.Windows.Forms.Padding(5);
    this.uitextBoxSend.ShowScrollBar = true;
    this.uitextBoxSend.ShowText = false;
    this.uitextBoxSend.Size = new System.Drawing.Size(308, 236);
    this.uitextBoxSend.TabIndex = 57;
    this.uitextBoxSend.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft;
    this.uitextBoxSend.Watermark = "";
    //
    // uibuttonStartServer
    //
    this.uibuttonStartServer.CircleColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))));
    this.uibuttonStartServer.Cursor = System.Windows.Forms.Cursors.Hand;
    this.uibuttonStartServer.Font = new System.Drawing.Font("宋体", 12F);
    this.uibuttonStartServer.Location = new System.Drawing.Point(544, 138);
    this.uibuttonStartServer.MinimumSize = new System.Drawing.Size(1, 1);
    this.uibuttonStartServer.Name = "uibuttonStartServer";
    this.uibuttonStartServer.Padding = new System.Windows.Forms.Padding(6);
    this.uibuttonStartServer.Radius = 0;
    this.uibuttonStartServer.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
    this.uibuttonStartServer.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
    this.uibuttonStartServer.Size = new System.Drawing.Size(100, 88);
    this.uibuttonStartServer.Symbol = 62074;
    this.uibuttonStartServer.SymbolSize = 44;
    this.uibuttonStartServer.TabIndex = 27;
    this.uibuttonStartServer.Text = "启动服务器";
    this.uibuttonStartServer.TextImageRelation = System.Windows.Forms.TextImageRelation.TextAboveImage;
    this.uibuttonStartServer.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    this.uibuttonStartServer.Click += new System.EventHandler(this.uibuttonStartServer_Click_1);
    //
    // uibuttonSend
    //
    this.uibuttonSend.CircleColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))));
    this.uibuttonSend.Cursor = System.Windows.Forms.Cursors.Hand;
    this.uibuttonSend.Font = new System.Drawing.Font("宋体", 12F);
    this.uibuttonSend.Location = new System.Drawing.Point(544, 463);
    this.uibuttonSend.MinimumSize = new System.Drawing.Size(1, 1);
    this.uibuttonSend.Name = "uibuttonSend";
    this.uibuttonSend.Padding = new System.Windows.Forms.Padding(0, 8, 0, 3);
    this.uibuttonSend.Radius = 0;
    this.uibuttonSend.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
    this.uibuttonSend.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
    this.uibuttonSend.Size = new System.Drawing.Size(100, 88);
    this.uibuttonSend.Style = Sunny.UI.UIStyle.Custom;
    this.uibuttonSend.Symbol = 62074;
    this.uibuttonSend.SymbolSize = 44;
    this.uibuttonSend.TabIndex = 59;
    this.uibuttonSend.Text = "发送数据";
    this.uibuttonSend.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    this.uibuttonSend.Click += new System.EventHandler(this.uibuttonSend_Click);
    //
    // uitextBoxReceive
    //
    this.uitextBoxReceive.ButtonWidth = 100;
    this.uitextBoxReceive.Cursor = System.Windows.Forms.Cursors.IBeam;
    this.uitextBoxReceive.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    this.uitextBoxReceive.Location = new System.Drawing.Point(132, 89);
    this.uitextBoxReceive.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
    this.uitextBoxReceive.MinimumSize = new System.Drawing.Size(1, 1);
    this.uitextBoxReceive.Multiline = true;
    this.uitextBoxReceive.Name = "uitextBoxReceive";
    this.uitextBoxReceive.Padding = new System.Windows.Forms.Padding(5);
    this.uitextBoxReceive.ShowScrollBar = true;
    this.uitextBoxReceive.ShowText = false;
    this.uitextBoxReceive.Size = new System.Drawing.Size(308, 236);
    this.uitextBoxReceive.TabIndex = 58;
    this.uitextBoxReceive.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft;
    this.uitextBoxReceive.Watermark = "";
    //
    // FormServer
    //
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
    this.ClientSize = new System.Drawing.Size(1044, 719);
    this.Controls.Add(this.uitextBoxReceive);
    this.Controls.Add(this.uibuttonSend);
    this.Controls.Add(this.uibuttonStartServer);
    this.Controls.Add(this.uitextBoxSend);
    this.Controls.Add(this.uiSmoothLabel1);
    this.Controls.Add(this.uiSmoothLabel2);
    this.Name = "FormServer";
    this.Text = "服务器";
    this.ZoomScaleRect = new System.Drawing.Rectangle(19, 19, 1044, 719);
    this.Load += new System.EventHandler(this.FormServer_Load);
    this.ResumeLayout(false);

    }

    #endregion

    private Sunny.UI.UISmoothLabel uiSmoothLabel2;
    private Sunny.UI.UISmoothLabel uiSmoothLabel1;
    private Sunny.UI.UITextBox uitextBoxSend;
    private Sunny.UI.UIHeaderButton uibuttonStartServer;
    private Sunny.UI.UIHeaderButton uibuttonSend;
    private Sunny.UI.UITextBox uitextBoxReceive;
    }
    }

    通过本次项目实践,我掌握了WinForm应用程序开发、TCP网络编程、多线程处理等关键技术,为今后的软件开发工作打下了坚实基础。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 基于SunnyUI的WinForm TCP服务器实现
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!