.Net TCP探索(一)——TCP服務端開發(同時監聽多個客戶端請求)

来源:https://www.cnblogs.com/fb208/archive/2019/10/18/11690288.html
-Advertisement-
Play Games

    最近在園子里看了大神寫的( "面試官,不要再問我三次握手和四次揮手" ),忍不住寫段程式來測試一番。     在網上找了很多例子,大多只實現了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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • @[toc] 前言 時間過得好快,在之前升級到3.0之後,就感覺好久沒再動過啥東西了,之前有問到Swagger的中文漢化,雖說我覺得這種操作的意義不是太大,也是多少鼓搗了下,其實個人感覺就是元素內容替換,既然可以執行js了那不就是網頁上隨便搞了,所以就沒往下再折騰,但是現在需要用到Excel的操作了 ...
  • 部署consul-docker鏡像 先搜索consul的docker鏡像 然後選擇了第一個,也就是官方鏡像 下載鏡像 然後運行鏡像 docker run -d --name consul -v /home/root/config:/config --restart=always\ -p 8300:8 ...
  • asp.net core 騰訊驗證碼的接入 Intro 之前使用的驗證碼服務是用的極驗驗證,而且是比較舊的,好久之前接入的,而且驗證碼服務依賴 Session,有點不太靈活,後來發現騰訊也有驗證碼服務,而且支持小程式,並且是唯一支持小程式的驗證碼。。(壟斷麽。。) 而且相比之下,騰訊驗證碼不需要依賴 ...
  • void Main() { var empList =new List<Employee> { new Employee {ID = 1, FName = "John", Age = 23, Sex = 'M'}, new Employee {ID = 2, FName = "Mary", Age ... ...
  • 通過重寫IsValid方向添加自定義驗證,MinValueField為需要比較的欄位名,MinDisplayName是顯示的名字。BaseCompareAttribute記錄的構造函數第三個參數為重寫FormatErrorMessage函數,以及提供比較值的類型轉換 具體是參考微軟兩個欄位比較是否相 ...
  • 主從表是配了級聯刪除的,如果通過導航屬性去除從表明細刪除時將報錯The relationship could not be changed because one or more of the foreign-key properties is non-nullable 通過實體導航屬性取出來的從表 ...
  • 設置winform窗體最大化,填滿整個屏幕 this.WindowState = FormWindowState.Maximized; ...
  • .net core 讀取配置文件亂碼;vs2019讀取appsettings.json亂碼問題; .net core 讀取appsettings.json亂碼問題;用notepad++或者其他編輯器打開,編碼格式轉換成UTF-8BOM後保存即可。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...