.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...\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;
        }
    }
}

測試效果:
tcp server test

完整代碼請關注:https://github.com/FB208/CodeSpace/tree/master/CodeSpace.CSharp/TCP.Client


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM