Socket非同步通信學習二

来源:http://www.cnblogs.com/gongheng/archive/2016/07/19/5683241.html
-Advertisement-
Play Games

接下來是伺服器部分,採用非同步模式,新建了一個AsynServer類,用於存放socket伺服器代碼,主要有4個方法: 有一個全局socket,下麵四個方法中都用到。 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.S ...


接下來是伺服器部分,採用非同步模式,新建了一個AsynServer類,用於存放socket伺服器代碼,主要有4個方法:

有一個全局socket,下麵四個方法中都用到。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

類框架如下:

1.構造方法public AsynServer(IPEndPoint endpoint,int listenMaxNum)

  用於初始化socket伺服器,IPEndPoint參數是socket綁定的終結點,listenMaxNum參數是監聽隊列的掛起的最大長度,代碼如下:

  public AsynServer(IPEndPoint endpoint,int listenMaxNum)
        {       
                socket.Bind(endpoint);      //綁定終結點
                socket.Listen(listenMaxNum);//將socket至於偵聽狀態,設置掛起隊列最大值為listenMaxNum
                Console.WriteLine("正在連接客戶端....");
                AsynAccept();         //開始非同步監聽
       //     return socket;
        }

2.非同步監聽方法public void AsynAccept()

public void AsynAccept()
        {
                socket.BeginAccept(asyncResult => {
                socket = socket.EndAccept(asyncResult);         //非同步監聽成功,返回socket
                Console.WriteLine("客戶端{0}非同步連接成功", socket.RemoteEndPoint.ToString());            
                AsynReceive();
                    AsynSend("Server:Hello,client!");
            }, null);
        }
View Code

需註意的是非同步socket的BeginAccept()方法必須以EndAccept()方法結束,EndAccept(asyncResult)通過回調BeginAccept中的asyncResult狀態信息返回socket,這個socket是與客戶端建立連接後的socket,需要把它賦給全局socket(後面的方法中會調用)。

另外,AsynAccept並不會阻塞主線程,因為系統會為BeginAccept()方法自動開一個線程,並阻塞該線程直到收到客戶端連接,回調lamda表達式中的接收代碼。

採用lamda變得式寫的回調函數,不熟悉的同學請惡補一下吧,用起來很方便的:-)

連接成功了會收到客戶端發來的信息,(AsynReceive()也是非同步的,不會阻礙主線程),並給客戶端發送問候信息,(AsynReceive()和AsynSend()都是非同步的,不會阻礙主線程)。

3.非同步接收方法private  void AsynReceive()

  private  void AsynReceive()
        {
            byte[] data = new byte[1024];//接收緩存
            string receiveStr;
            socket.BeginReceive(data, 0, data.Length, SocketFlags.None, asyncResult => {
                int length = socket.EndReceive(asyncResult);
                if (length != 0)
                {
                    receiveStr = Encoding.ASCII.GetString(data, 0, length);//獲取緩存中的信息
                    Console.WriteLine(receiveStr);
                      
                    AsynReceive();//繼續開新線程接收
                }
                else {
                        
                    Console.WriteLine("客戶端{0}:關閉socket連接", socket.RemoteEndPoint.ToString());//socket.RemoteEndPoint.ToString()是客戶端IP地址
                    socket.Close();
                }
            }, null);
            
            
        }
AsynReceive()

4.非同步發送方法public void AsynSend()

 public void AsynSend(string msg)
        {
            byte[] data = Encoding.UTF8.GetBytes(msg);
            socket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
            {
                int length = socket.EndSend(asyncResult);
                Console.WriteLine("message send to {0} successfully", socket.RemoteEndPoint.ToString());
            }, null);            
        }
public void AsynSend(string msg)

因為socket收發都是採用位元組流的形式,所以接收需要用byte[] data = new byte[1024],緩存收到的位元組流,然後通過Encoding.ASCII.GetString(data, 0, length)方法把位元組流轉化為字元串輸出;發送通過byte[] data = Encoding.UTF8.GetBytes(msg),把字元串信息轉化為位元組流發送。EndReceive(),EndSend()方法返回的都是收發位元組數(int)

以上都是最簡單的,只能實現基本的通信功能,後期會在此基礎上完善,幫助初學者少走彎路,我當時可是學的頭昏眼花-_-||

下篇是採用與伺服器完全不同模式的客戶端,同步模式


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

-Advertisement-
Play Games
更多相關文章
  • 1.說一下這次部署的程式說明吧,兩個java程式,還有個java web項目 2.關於java程式,本來是想著使用javac和java進行編譯、運行的,但是項目帶package和jar包,所以就各種麻煩,最後就乾脆在eclipse中導出jar,直接jar -jar project.jar完事; 3. ...
  • 原文鏈接:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=116213&id=3376727 最近在網路編程使用的過程中,發現errno會經常使用。因此決定在此做個留用,以備以後使用。。。 雖然errno是非線程安全的,但是可以通過幾種 ...
  • 接上篇文章,在已經部署好Kubernetes的基礎上部署kubernetes dashboard,它是官方提供的用戶管理Kubernets集群可視化工具;部署dashboard其實和在kubernets部署其他的應用一樣,創建dashboard所需的Replication Controller、Se ...
  • 一、上下文對象簡介 在MVC項目中添加一個EDMX文件的時候會添加很多文件進來,其中包括.Context.tt,和.tt這兩個T4模板,其中.Context.tt是用來生成上下文對象的T4模板,.tt生成實體類的T4模板。如圖: 實體框架 會幫我們生成XML文件和實體類,這裡它已經生成了我們要的XM ...
  • 1、Replace C#:(using System.Text.RegularExpressions;) string txt = Regex.Replace(txtLog.Text.ToString(), "/(^\\s*)|(\\s*$)/g", ""); js: var txt = docum ...
  • 在項目中經常用到DataTable,如果DataTable使用得當,不僅能使程式簡潔實用,而且能夠提高性能,達到事半功倍的效果,現對DataTable的使用技巧進行一下總結。 一、DataTable簡介 (1)構造函數 DataTable() 不帶參數初始化DataTable 類的新實例。 Data ...
  • 頁面刷新 window.location.reload(); window.location.reload(); 跳轉指定頁面 Response.Redirect(Url); 返回上一頁 window.history.back(); 返回下一頁 window.history.forward(); 返 ...
  • 一、抽象類: 抽象類是特殊的類,只是不能被實例化;除此以外,具有類的其他特性;重要的是抽象類可以包括抽象方法,這是普通類所不能的。抽象方法只能聲明於抽象類中,且不包含任何實現,派生類必須覆蓋它們。另外,抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋,如果不覆蓋,則其派生類必須覆蓋它們 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...