当前位置:   article > 正文

C# 简易TCP网口调试助手(二) 服务端Server_tcp调试助手

tcp调试助手

 上位机开发工作中开始频繁涉及到网口、串口的通讯,网上找了各种资料和帖子都没怎么找到好用的开源代码或者工具。目前找到几个好一点的方式来实现的网口和串口通讯工具包,先写个好用的TCP的negut包记录下来,将使用的步骤写下来做个记录。

  本博客主要用来记录自己学到的东西,用于以后回来查看和使用。也会标注来源,各位若是对某项内容感兴趣,可去来源处更加细致的学习

    实现效果如下;1、可以监听多个客户端,和限制客户端的连接。2、接收和转发5000行大数据量,快速且无错误。3、可以设置心跳功能,客户端在指定时间内一直不发送数据,会被自动断开。

  注:已经看过TCP网口调试助手(一)的朋友 ,可以直接跳到二、3处开始看起

一、使用的环境

开发工具:Visual Studio 2022

用户界面框架:winform

框架版本:.NET Framework 4.8

二、项目搭建

1、新建winform项目

  选择 “Windows窗体应用(NET Framework)” 项目

  输入项目名称:TCP_Server,使用框架为.NET Framework 4.8

2、添加nuget包

  右键项目,准备添加TCP的nuget包

  使用的nuget包为:STTech.ByteslO.Tcp,版本:2.14.6-alpha0225(也可选择最新版本下载,不必强求版本一致),在nuget管理界面的浏览页面下搜索bytesio,找到nuget包。点击安装并确定

3、创建界面

三、主要代码编写

1、TcpServer的“监听”和“关闭监听”,以及相关事件提示

 实现代码如下:

  1. using STTech.BytesIO.Tcp;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. namespace TCP_Server
  12. {
  13. public partial class Form1 : Form
  14. {
  15. private TcpServer server;
  16. public Form1()
  17. {
  18. InitializeComponent();
  19. //初始化server对象
  20. server = new TcpServer();
  21. //设置server的端口号
  22. server.Port = int.Parse(toolStrip_tbx_port.Text);
  23. //服务启动时触发的事件
  24. server.Started += Server_Started;
  25. //服务关闭时触发的事件
  26. server.Closed += Server_Closed;
  27. //客户端连接时触发的事件
  28. server.ClientConnected += Server_ClientConnected;
  29. //客户端断开连接时触发的事件
  30. server.ClientDisconnected += Server_ClientDisconnected;
  31. }
  32. //客户端断开连接时触发的事件,对应的处理函数
  33. private void Server_ClientDisconnected(object sender, ClientDisconnectedEventArgs e)
  34. {
  35. Print($"客户端[{e.Client.Host}:{e.Client.Port}]断开连接");
  36. }
  37. //客户端连接时触发的事件,对应的处理函数
  38. private void Server_ClientConnected(object sender, ClientConnectedEventArgs e)
  39. {
  40. Print($"客户端[{e.Client.Host}:{e.Client.Port}]连接成功");
  41. }
  42. //服务关闭时触发的事件,对应的处理函数
  43. private void Server_Closed(object sender, EventArgs e)
  44. {
  45. Print("停止监听");
  46. }
  47. //服务启动时触发的事件,对应的处理函数
  48. private void Server_Started(object sender, EventArgs e)
  49. {
  50. Print("开始监听");
  51. }
  52. private void Print(string msg)
  53. {
  54. //线程的修改直接更新到UI主线程是不被允许的,这里通过调用Form的Invoke方法跨线程访问控件
  55. this.Invoke(new Action(() =>
  56. {
  57. rtbx_log.AppendText($"[{DateTime.Now}] {msg}\r\n");
  58. }));
  59. }
  60. private void MenuItem_startListen_Click(object sender, EventArgs e)
  61. {
  62. //开始监听
  63. server.StartAsync();
  64. }
  65. private void MenuItem_closeListen_Click(object sender, EventArgs e)
  66. {
  67. //停止监听
  68. server.CloseAsync();
  69. }
  70. }
  71. }

2、在服务端接收到客户端发送的消息后做的处理

添加修改的部分代码如下:

  1. //客户端连接时触发的事件,对应的处理函数
  2. private void Server_ClientConnected(object sender, ClientConnectedEventArgs e)
  3. {
  4. Print($"客户端[{e.Client.Host}:{e.Client.Port}]连接成功");
  5. //当客户端有数据返回时触发事件
  6. e.Client.OnDataReceived += Client_OnDataReceived;
  7. }
  8. //处理客户端返回过来数据
  9. private void Client_OnDataReceived(object sender, STTech.BytesIO.Core.DataReceivedEventArgs e)
  10. {
  11. TcpClient tcpClient = (TcpClient)sender;
  12. Print($"来自客户端[{tcpClient.RemoteEndPoint}]的消息:{e.Data.EncodeToString("GBK")}");
  13. }

3、收到某个客户端发送的消息后,转发给所有其他客户端

  这样的效果类似于聊天室,A群友发送的消息,大家伙儿都能看得到

代码量不多,增加代码如下:

  1. //处理客户端返回过来数据
  2. private void Client_OnDataReceived(object sender, STTech.BytesIO.Core.DataReceivedEventArgs e)
  3. {
  4. TcpClient tcpClient = (TcpClient)sender;
  5. Print($"来自客户端[{tcpClient.RemoteEndPoint}]的消息:{e.Data.EncodeToString("GBK")}");
  6. //收到某个客户端数据后,遍历server中客户端
  7. foreach(TcpClient client in server.Clients)
  8. {
  9. //找到非当前发数据的客户端
  10. if (client != tcpClient)
  11. {
  12. //给这个客户端转发消息
  13. client.SendAsync(e.Data);
  14. }
  15. }
  16. }

4、服务端在客户端连接时进行限制

  可以设置服务端的容量上限,也可以限制某个区段的ip地址不可以连接我们的服务端。代码如下:

  1. public Form1()
  2. {
  3. InitializeComponent();
  4. //初始化server对象
  5. server = new TcpServer();
  6. //设置server的端口号
  7. server.Port = int.Parse(toolStrip_tbx_port.Text);
  8. //服务启动时触发的事件
  9. server.Started += Server_Started;
  10. //服务关闭时触发的事件
  11. server.Closed += Server_Closed;
  12. //客户端连接时触发的事件
  13. server.ClientConnected += Server_ClientConnected;
  14. //客户端断开连接时触发的事件
  15. server.ClientDisconnected += Server_ClientDisconnected;
  16. //接收客户端连接时的处理过程,加个服务端上限为只能容纳三个客户端
  17. server.ClientConnectionAcceptedHandle = (s, e) =>
  18. {
  19. if (server.Clients.Count() < 3)
  20. {
  21. return true;
  22. }
  23. else
  24. {
  25. Print($"服务器已满,关闭客户端[{e.ClientSocket.RemoteEndPoint}]的连接");
  26. return false;
  27. }
  28. };
  29. }

5、服务端添加和客户端的心跳功能

  如果某个客户端在一定时间内没有给服务端发送数据,就会自动断开。使用代码如下:

  1. //客户端连接时触发的事件,对应的处理函数
  2. private void Server_ClientConnected(object sender, ClientConnectedEventArgs e)
  3. {
  4. Print($"客户端[{e.Client.Host}:{e.Client.Port}]连接成功");
  5. //当客户端有数据返回时触发事件
  6. e.Client.OnDataReceived += Client_OnDataReceived;
  7. //和客户端建立心跳,如果客户端多长时间没回消息,就断开连接,3000单位是ms
  8. e.Client.UseHeartbeatTimeout(3000);
  9. }

6、完整代码

  1. using STTech.BytesIO.Core;
  2. using STTech.BytesIO.Tcp;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Data;
  7. using System.Drawing;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. namespace TCP_Server
  13. {
  14. public partial class Form1 : Form
  15. {
  16. private TcpServer server;
  17. public Form1()
  18. {
  19. InitializeComponent();
  20. //初始化server对象
  21. server = new TcpServer();
  22. //设置server的端口号
  23. server.Port = int.Parse(toolStrip_tbx_port.Text);
  24. //服务启动时触发的事件
  25. server.Started += Server_Started;
  26. //服务关闭时触发的事件
  27. server.Closed += Server_Closed;
  28. //客户端连接时触发的事件
  29. server.ClientConnected += Server_ClientConnected;
  30. //客户端断开连接时触发的事件
  31. server.ClientDisconnected += Server_ClientDisconnected;
  32. //接收客户端连接时的处理过程,加个服务端上限为只能容纳三个客户端
  33. server.ClientConnectionAcceptedHandle = (s, e) =>
  34. {
  35. if (server.Clients.Count() < 3)
  36. {
  37. return true;
  38. }
  39. else
  40. {
  41. Print($"服务器已满,关闭客户端[{e.ClientSocket.RemoteEndPoint}]的连接");
  42. return false;
  43. }
  44. };
  45. }
  46. //客户端断开连接时触发的事件,对应的处理函数
  47. private void Server_ClientDisconnected(object sender, ClientDisconnectedEventArgs e)
  48. {
  49. Print($"客户端[{e.Client.Host}:{e.Client.Port}]断开连接");
  50. }
  51. //客户端连接时触发的事件,对应的处理函数
  52. private void Server_ClientConnected(object sender, ClientConnectedEventArgs e)
  53. {
  54. Print($"客户端[{e.Client.Host}:{e.Client.Port}]连接成功");
  55. //当客户端有数据返回时触发事件
  56. e.Client.OnDataReceived += Client_OnDataReceived;
  57. //和客户端建立心跳,如果客户端多长时间没回消息,就断开连接,3000单位是ms
  58. e.Client.UseHeartbeatTimeout(3000);
  59. }
  60. //处理客户端返回过来数据
  61. private void Client_OnDataReceived(object sender, STTech.BytesIO.Core.DataReceivedEventArgs e)
  62. {
  63. TcpClient tcpClient = (TcpClient)sender;
  64. Print($"来自客户端[{tcpClient.RemoteEndPoint}]的消息:{e.Data.EncodeToString("GBK")}");
  65. //收到某个客户端数据后,遍历server中客户端
  66. foreach(TcpClient client in server.Clients)
  67. {
  68. //找到非当前发数据的客户端
  69. if (client != tcpClient)
  70. {
  71. //给这个客户端转发消息
  72. client.SendAsync(e.Data);
  73. }
  74. }
  75. }
  76. //服务关闭时触发的事件,对应的处理函数
  77. private void Server_Closed(object sender, EventArgs e)
  78. {
  79. Print("停止监听");
  80. }
  81. //服务启动时触发的事件,对应的处理函数
  82. private void Server_Started(object sender, EventArgs e)
  83. {
  84. Print("开始监听");
  85. }
  86. private void Print(string msg)
  87. {
  88. //线程的修改直接更新到UI主线程是不被允许的,这里通过调用Form的Invoke方法跨线程访问控件
  89. this.Invoke(new Action(() =>
  90. {
  91. rtbx_log.AppendText($"[{DateTime.Now}] {msg}\r\n");
  92. }));
  93. }
  94. private void MenuItem_startListen_Click(object sender, EventArgs e)
  95. {
  96. //开始监听
  97. server.StartAsync();
  98. }
  99. private void MenuItem_closeListen_Click(object sender, EventArgs e)
  100. {
  101. //停止监听
  102. server.CloseAsync();
  103. }
  104. }
  105. }

五、总结

  主要使用了服务端和客户端的连接、接收数据、群转发接收到的数据、对客户端的限制连接和心跳功能。传输速度不错,大数据量传输未出错。

原内容出处:C# TCP服务端_哔哩哔哩_bilibili

注:单身狗注意,原视频狗粮很多!!!

源代码(本文中自己试验写的程序):TCP_Server · jifengtu/ShareSpace - 码云 - 开源中国 (gitee.com)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/583661
推荐阅读
相关标签
  

闽ICP备14008679号