C#Socket 網路通信非同步處理 SocketAsyncEventArgs

来源:http://www.cnblogs.com/heyangyi/archive/2017/07/28/7250839.html
-Advertisement-
Play Games

C#Socket 網路通信非同步處理 SocketAsyncEventArgs 非同步套接字操作 1.服務端簡單實現: 2.客戶端簡單實現: ...


C#Socket 網路通信非同步處理 SocketAsyncEventArgs 非同步套接字操作

1.服務端簡單實現:

    public partial class Form_Server : Form
    {
        private Socket socket;

        public Form_Server()
        {
            InitializeComponent();
        }

        private void Form_Server_Load(object sender, EventArgs e)
        {
            try
            {
                //獲取本地ip地址
                IPAddress ipaddress = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
                txt_ip.Text = ipaddress.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //開啟Socket監聽
        private void btn_listent_open_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(txt_ip.Text))
                {
                    MessageBox.Show("請輸入IP地址");
                }

                //打開監聽
                IPAddress ip = IPAddress.Parse(txt_ip.Text);
                IPEndPoint localEP = new IPEndPoint(ip, Int32.Parse(txt_port.Text));
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Bind(localEP);
                socket.Listen(1000);

                //AcceptAsync非同步方式
                SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();
                socketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(socketAsyncEventArgs_Completed_AcceptAsync);
                socketAsyncEventArgs.RemoteEndPoint = localEP;
                socketAsyncEventArgs.UserToken = socket;
                socket.AcceptAsync(socketAsyncEventArgs);
               
                //消息提示
                this.lb_msg.Items.Add("[服務端]:");
                this.lb_msg.Items.Add("         監聽成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //開始一個非同步操作來接受一個傳入的連接嘗試
        void socketAsyncEventArgs_Completed_AcceptAsync(object ServerSocket, SocketAsyncEventArgs e)
        {
            //已關閉,重疊的操作被中止
            if (e.SocketError == SocketError.OperationAborted)
            {
                //已關閉,重疊的操作被中止
                this.lb_msg.Invoke(new Action(() =>
                {
                    this.lb_msg.Items.Add("[服戶端]:");
                    this.lb_msg.Items.Add("         socketAsyncEventArgs_Completed_AcceptAsync:已關閉,重疊的操作被中止>SocketError:OperationAborted");
                }));
                return;
            }

            //此連接由遠程對等電腦重置
            if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0)
            {
                //此連接由遠程對等電腦重置
                this.lb_msg.Invoke(new Action(() =>
                {
                    this.lb_msg.Items.Add("[服戶端]:");
                    this.lb_msg.Items.Add("         socketAsyncEventArgs_Completed_AcceptAsync:此連接由遠程對等電腦重置>SocketError:ConnectionReset");
                }));
                return;
            }
            
            if (e.LastOperation == SocketAsyncOperation.Accept)
            {
                try
                {
                    Socket acceptSocket = e.AcceptSocket;
                     
                    //開始一個非同步請求以便從連接的 System.Net.Sockets.Socket 對象中接收數據
                    SocketAsyncEventArgs socketAsyncEventArgsReceiveAsync = new SocketAsyncEventArgs();
                    socketAsyncEventArgsReceiveAsync.UserToken = acceptSocket;
                    byte[] receiveBuff = new byte[1024 * 4];
                    socketAsyncEventArgsReceiveAsync.SetBuffer(receiveBuff, 0, receiveBuff.Length);
                    socketAsyncEventArgsReceiveAsync.Completed += new EventHandler<SocketAsyncEventArgs>(socketAsyncEventArgs_Completed_ReceiveAsync);
                    acceptSocket.ReceiveAsync(socketAsyncEventArgsReceiveAsync);

                    //消息提示
                    this.lb_msg.Invoke(new Action(() =>
                    {
                        this.lb_msg.Items.Add("[客戶端]:");
                        this.lb_msg.Items.Add("         連接成功");
                    }));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                //開始一個非同步操作來接受一個傳入的連接嘗試,遞歸
                e.AcceptSocket = null;
                socket.AcceptAsync(e);
            }
        }

        //開始一個非同步請求以便從連接的 System.Net.Sockets.Socket 對象中接收數據
        void socketAsyncEventArgs_Completed_ReceiveAsync(object acceptSocket, SocketAsyncEventArgs e)
        {
            //已關閉,重疊的操作被中止
            if (e.SocketError == SocketError.OperationAborted)
            {
                //已關閉,重疊的操作被中止 
                this.lb_msg.Invoke(new Action(() =>
                {
                    this.lb_msg.Items.Add("[服戶端]:");
                    this.lb_msg.Items.Add("         socketAsyncEventArgs_Completed_ReceiveAsync:已關閉,重疊的操作被中止>SocketError:OperationAborted");
                }));
                return;
            }

            //此連接由遠程對等電腦重置
            if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0)
            {
                //此連接由遠程對等電腦重置
                this.lb_msg.Invoke(new Action(() => {
                    this.lb_msg.Items.Add("[服戶端]:");
                    this.lb_msg.Items.Add("         socketAsyncEventArgs_Completed_ReceiveAsync:此連接由遠程對等電腦重置>SocketError:ConnectionReset");
                }));
                return;
            }
            
            if (e.SocketError == SocketError.Success && e.Buffer.Length > 0)
            {
                try
                {
                    Socket socket = acceptSocket as Socket;

                    string ipAddress = socket.RemoteEndPoint.ToString();
                    int lengthuffer = e.BytesTransferred;

                    byte[] receiveBuffer = e.Buffer;
                    byte[] buffer = new byte[lengthuffer];
                    Buffer.BlockCopy(receiveBuffer, 0, buffer, 0, lengthuffer);
                    string message = Encoding.UTF8.GetString(buffer);

                    this.lb_msg.Invoke(new Action(() =>
                    {
                        this.lb_msg.Items.Add("[客戶端]:");
                        this.lb_msg.Items.Add("         " + message);
                    }));

                    socket.Send(Encoding.UTF8.GetBytes(string.Format("收到消息{0}:{1}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), message)));
                    socket.ReceiveAsync(e);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        //關閉Socket監聽
        private void btn_listent_Close_Click(object sender, EventArgs e)
        {
            try
            {
                if (socket != null)
                {
                    socket.Close();
                }
                this.lb_msg.Items.Add("[服務端]:");
                this.lb_msg.Items.Add("         關閉監聽成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
           
        }
    }

2.客戶端簡單實現:

    public partial class ClientMainForm : Form
    {
        private Socket _socket;
        public ClientMainForm()
        {
            InitializeComponent();
        }

        //登錄
        private void btn_login_Click(object sender, EventArgs e)
        {
            try
            {
                IPAddress ip = IPAddress.Parse(this.txt_ip.Text);
                IPEndPoint ipendPoint = new IPEndPoint(ip, Int32.Parse(this.txt_port.Text));

                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _socket.Connect(ipendPoint);

                this.lb_msg.Items.Add("[客戶端]:");
                this.lb_msg.Items.Add("         連接服務端成功");

                //開啟新的接受消息非同步操作事件
                SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();
                //設置消息的緩衝區大小
                byte[] receiveBuff = new byte[1024 * 4];
                socketAsyncEventArgs.SetBuffer(receiveBuff, 0, receiveBuff.Length);
                socketAsyncEventArgs.UserToken = _socket;
                //綁定回調事件
                socketAsyncEventArgs.Completed += socketAsyncEventArgs_Completed_ReceiveAsync;
                _socket.ReceiveAsync(socketAsyncEventArgs);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //開始一個非同步請求以便從連接的 System.Net.Sockets.Socket 對象中接收數據。
        void socketAsyncEventArgs_Completed_ReceiveAsync(object sender, SocketAsyncEventArgs e)
        {
            //已關閉,重疊的操作被中止
            if (e.SocketError == SocketError.OperationAborted)
            {
                this.lb_msg.Invoke(new Action(() =>
                {
                    this.lb_msg.Items.Add("[客戶端]:");
                    this.lb_msg.Items.Add("         socketAsyncEventArgs_Completed_ReceiveAsync:已關閉,重疊的操作被中止:OperationAborted");
                }));
                return;
            }

            //此連接由遠程對等電腦重置
            if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0)
            {
                //此連接由遠程對等電腦重置
                this.lb_msg.Invoke(new Action(() =>
                {
                    this.lb_msg.Items.Add("[客戶端]:");
                    this.lb_msg.Items.Add("         socketAsyncEventArgs_Completed_ReceiveAsync:此連接由遠程對等電腦重置:ConnectionReset");
                }));
                return; 
            }

            Socket socket = sender as Socket;
            if(e.SocketError==SocketError.Success&&e.Buffer.Length>0)
            {
                string ipAddress = socket.RemoteEndPoint.ToString();
                int lengthuffer = e.BytesTransferred;

                byte[] receiveBuffer = e.Buffer;
                byte[] buffer = new byte[lengthuffer];
                Buffer.BlockCopy(receiveBuffer, 0, buffer, 0, lengthuffer);
                string message = Encoding.UTF8.GetString(buffer);


                this.lb_msg.Invoke(new Action(() =>
                {
                    this.lb_msg.Items.Add("[服務戶端]:");
                    this.lb_msg.Items.Add("         " + message);
                }));
              
                socket.ReceiveAsync(e);
            }
        }

        //發送消息
        private void btn_sendmsg_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txt_msg.Text))
            {
                MessageBox.Show("請輸入消息");
            }
            else
            {
                _socket.Send(System.Text.Encoding.UTF8.GetBytes(txt_msg.Text));
            }
        }
    }

 


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

-Advertisement-
Play Games
更多相關文章
  • 一、下載模板 http://www.zabbix.org/wiki/Zabbix_Templates 我這邊ESXI 版本是6.0的,但是模板只有5,也可以用 二、添加模板 配置 > 模板 > 載入 三、創建主機群 配置 主機群組 創建主機群組 四、添加主機 配置 主機 創建主機 選擇 SNMP介面 ...
  • 作者: "zyl910" 一、緣由 “Sandcastle Help File Builder”(簡稱SHFB)是一個很好用.NET 幫助文檔生成工具。 但它的每個版本支持的VS版本範圍有限,且官網沒有明確說明它與VS版本的區別。導致經常出現“明明裝了SHFB,但VS打開不了它的項目”問題。 這時只 ...
  • 前三篇的博文結合了C#的Demo對記憶體數據修改一類的掛剖析了原理,利用C#語言調用Windows API,我們其實已經寫出了一個簡單的記憶體掃描工具,但是它存在一些缺陷,比如說只能所搜索單一類型數值(整型),只能搜索確定的數值,比如1000、2000,而不能進行模糊搜索,比如搜索某個值變小了,或者在某 ...
  • C#中為正則表達式的使用提供了非常強大的功能,這就是Regex類。這個包包含於System.Text.RegularExpressions命名空間下麵,而這個命名空間所在DLL基本上在所有的項目模板中都不需要單獨去添加引用,可以直接使用。 1、定義一個Regex類的實例 Regex regex = ...
  • 一些說在前面的: RSA是一種塊加密的演算法,所以對於明文需要將他們分成固定的塊長度,考慮到輸入的數據長度的問題,所以加解密的填充有好幾種: 無填充,就是直接對明文進行加密 PKCS1。將數據長度分成密鑰長度-11byte,比如密鑰是1024bit,那麼長度就是1024/8-11=117bytes,具 ...
  • 一、String.Split方法提供瞭如下6個重載函數: 名稱說明 String.Split (Char[]) 返回包含此實例中的子字元串(由指定 Char 數組的元素分隔)的 String 數組。 由 .NET Compact Framework 支持。 String.Split (Char[], ...
  • 最近新上線了一個網站,專門收集網上簽到賺錢,有獎活動等等的網站 我就要集分寶 http://www.591jfb.com。新建立 了一個欄目“每日更新”,這樣就需要每天都登錄到網站後臺去發佈文章,感覺有些繁瑣,於是就想找點省勁的辦法,於是便有了此文。 搜索下載了蘇飛提供的httphelper,比著例 ...
  • Owin Startup 類解析 每個 Owin 程式都有 startup 類,在這個 startup 類裡面你可以指定應用程式管道模型中的組件。你可以通過不同的方式來連接你的 startup 類和運行時,這些取決於你選擇的宿主模型(OwinHost, IIS, and IIS-Express)。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...