最近在园子里看了大神写的 (面试官, 不要再问我三次握手和四次挥手), 忍不住写段程序来测试一番.
在网上找了很多例子, 大多只实现了 TCP 点对点通讯, 但实际应用中, 一个服务器端口往往要监听多个客户端发来的消息.
测试工具下载:
本例采用 System.Threading 实现多线程监听, 下面只介绍核心代码, 省略了消息提示和错误处理, 可以从我的 GitHub 获取完整代码:
数据声明:
- private string _ip;//IP
- private int _port;// 端口
- // 客户端集合
- public static List<TcpClientModel> clients = new List<TcpClientModel>
- private static byte[] bytes = new byte[1024 * 100];
- /// <summary>
- /// 用于存储客户端
- /// </summary>
- public class TcpClientModel
- {
- /// <summary>
- /// IP:Port
- /// </summary>
- public string RemoteEndPoint { get; set; }
- /// <summary>
- /// 客户端链接对象
- /// </summary>
- public TcpClient TcpClient { get; set; }
- }
启动监听:
- /// 启动监听
- void Init()
- {
- try
- {
- IPAddress ip = IPAddress.Parse(_ip);
- int port = _port;
- TcpListener listener = new TcpListener(ip, port);
- // 启动监听
- listener.Start();
- tb_console.AppendText($"Listener...\r\n");
- // 异步接收 递归循环接收多个客户端
- listener.BeginAcceptTcpClient(new AsyncCallback(GetAcceptTcpclient), listener);
- }
- catch (Exception ex)
- {
- }
- }
接收客户端:
- private void GetAcceptTcpclient(IAsyncResult State)
- {
- // 处理多个客户端接入
- TcpListener listener = (TcpListener)State.AsyncState;
- // 接收到客户端请求
- TcpClient client = listener.EndAcceptTcpClient(State);
- // 保存到客户端集合中
- clients.Add(new TcpClientModel() { TcpClient = client, RemoteEndPoint = client.Client.RemoteEndPoint.ToString() });
- // 开启线程用来持续接收来自客户端的数据
- Thread myThread = new Thread(() =>
- {
- ReceiveMsgFromClient(client);
- });
- myThread.Start();
- listener.BeginAcceptTcpClient(new AsyncCallback(GetAcceptTcpclient), listener);
- }
接收消息并响应客户端:
- private void ReceiveMsgFromClient(object reciveClient)
- {
- TcpClient client = reciveClient as TcpClient;
- if (client == null)
- {
- return;
- }
- while (true)
- {
- try
- {
- NetworkStream stream = client.GetStream();
- int num = stream.Read(bytes, 0, bytes.Length); // 将数据读到 result 中, 并返回字符长度
- if (num != 0)
- {
- // 把字节数组中流存储的数据以字符串方式赋值给 str
- // 这里就是接收到的客户端消息
- string str = Encoding.UTF8.GetString(bytes, 0, num);
- // 给客户端返回一个消息
- string msg = "Your message has been received by the server[" + str + "]";
- bool result = TCPHelper.SendToClient(client, msg, out msg);
- if (!result)
- {
- // 发送失败
- }
- }
- else
- {
- // 这里需要注意 当 num=0 时表明客户端已经断开连接, 需要结束循环, 不然会死循环一直卡住
- break;
- }
- }
- catch (Exception ex)
- {
- // 链接失败 从集合中移除出错客户端
- clients.Remove(clients.FirstOrDefault(m => m.RemoteEndPoint == client.Client.RemoteEndPoint.ToString()));
- break;
- }
- }
- }
从服务器向客户端发送消息的工具类:
- public static class TCPHelper
- {
- public static bool SendToClient(TcpClient client, string message,out string errorMsg)
- {
- try
- {
- byte[] bytes = new byte[1024 * 100];
- bytes = Encoding.UTF8.GetBytes(message);
- NetworkStream stream = client.GetStream();
- stream.Write(bytes, 0, bytes.Length);
- stream.Flush();
- errorMsg = "";
- return true;
- }
- catch (Exception ex)
- {
- errorMsg = ex.Message;
- return false;
- }
- }
- }
测试效果:
完整代码请关注:
来源: https://www.cnblogs.com/fb208/p/11690288.html