zoukankan      html  css  js  c++  java
  • .Net TCP探索(一)——TCP服务端开发(同时监听多个客户端请求)

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

        在网上找了很多例子,大多只实现了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...
    ");
            //异步接收 递归循环接收多个客户端
            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

  • 相关阅读:
    android应用程序的混淆打包
    在android market发布个人免费应用的步骤
    Eclipse使用教程之精华篇
    Android简单封装类似JQuery异步请求
    android自动打包方法(ant+proguard+签名)
    Android虚拟键盘弹出时挡住EditText解决方法
    android绝对布局
    Android访问php webservice
    Android SDK中 tools 工具介绍
    JSON 之JAVA 解析
  • 原文地址:https://www.cnblogs.com/fb208/p/11690288.html
Copyright © 2011-2022 走看看