.Net TCP探索(一)——TCP服务端开发(同时监听多个客户端请求)

  • 2019 年 10 月 18 日
  • 笔记

    最近在园子里看了大神写的(面试官,不要再问我三次握手和四次挥手),忍不住写段程序来测试一番。

    在网上找了很多例子,大多只实现了TCP点对点通讯,但实际应用中,一个服务器端口往往要监听多个客户端发来的消息。

测试工具下载:https://download.csdn.net/download/nbyanghuichao/11872360
    本例采用System.Threading实现多线程监听,下面只介绍核心代码,省略了消息提示和错误处理,可以从我的GitHub获取完整代码:https://github.com/FB208/CodeSpace/tree/master/CodeSpace.CSharp/TCP.Client

数据声明:

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...rn");          //异步接收 递归循环接收多个客户端          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;          }      }  }

测试效果:
tcp server test

完整代码请关注:https://github.com/FB208/CodeSpace/tree/master/CodeSpace.CSharp/TCP.Client