事件驅動的TCP協議Socket通信


事件驅動的TCP協議Socket通信

介紹

常規的Socket通信案例一般都是在某個線程中建立連接,然后用一個while(true)循環判斷是或否有數據傳輸,但是這種方法有局限性。

1、收到消息在處理過程中無法接受新消息

2、線程容易堵塞

3、需要客戶端服務端雙發進行心跳響應

事件驅動的方式可以有效的提高Socket通信效率,讓在一端有操作的同時,可以觸發另一端的事件。

類似工具庫:Cowboy.Socket、FastSocket

使用方法

1、打開VS,在Nuget里搜索SuperSocket

2、安裝SuperSocket.Client和SuperSocket

image-20200228133141918

3、服務端監聽端口以及注冊事件

AppServer appServer;
appServer = new AppServer();
            if (!appServer.Setup(int.Parse(txt_port.Text)))
            {
                SetMessage("Failed to Setup");
                return;
            }
            if (!appServer.Start())
            {
                SetMessage("Failed to Start");
                return;
            }
            else
            {
                SetMessage("開啟監聽");
            }
            //SuperSocket自定義了三個事件 ,連接事件,接收事件,關閉事件
            appServer.NewSessionConnected += appServer_NewSessionConnected;
            appServer.NewRequestReceived += appServer_NewRequestReceived;
            appServer.SessionClosed += appServer_SessionClosed;

4、服務端事件

void appServer_NewSessionConnected(AppSession session)
        {
            //有新連接的時候,添加記錄  session.LocalEndPoint屬性獲取當前session的ip和端口號
            //AppSession 代表一個和客戶端的邏輯連接,基於連接的操作應該定於在該類之中。你可以用該類的實例發送數據到客戶端,接收客戶端發送的數據或者關閉連接。

            //獲取遠程客戶端的ip端口號
            ipAddress_Connect = session.RemoteEndPoint.ToString();
            ComboboxHandle(ipAddress_Connect, OperateType.Add);
            sessionList.Add(ipAddress_Connect, session);
            SetMessage(ipAddress_Connect + "已連接!");
        }

        /// <summary>
        /// 接收數據
        /// </summary>
        /// <param name="session"></param>
        /// <param name="requestInfo"></param>
        void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
        {
            //requestInfo.Key 是請求的命令行用空格分隔開的第一部分
            //requestInfo.Parameters 是用空格分隔開的其余部分
            //requestInfo.Body 是出了請求頭之外的所有內容
            
            ipAddress_Receive = session.RemoteEndPoint.ToString();
            SetMessage("收到" + ipAddress_Receive + "數據: "+requestInfo.Key +" "+ requestInfo.Body);
        }

        /// <summary>
        /// 關閉連接
        /// </summary>
        /// <param name="session"></param>
        /// <param name="value"></param>
        void appServer_SessionClosed(AppSession session, SocketBase.CloseReason value)
        {   
            ipAddress_Close = session.RemoteEndPoint.ToString();
            ComboboxHandle(ipAddress_Close, OperateType.Remove);
            sessionList.Remove(ipAddress_Close);
            SetMessage(ipAddress_Close + "已關閉連接!");
        }

5、客戶端建立連接以及注冊事件

SuperSocket.ClientEngine.AsyncTcpSession async=new AsyncTcpSession();
async.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
async.Connected += client_Connected;
            // 發生錯誤的處理
            async.Error += client_Error;
            // 收到服務器數據事件
            async.DataReceived += client_DataReceived;
            async.Closed += client_Closed;

6、客戶端事件

        void client_Error(object sender, ErrorEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
        }

        void client_Connected(object sender, EventArgs e)
        {
            Console.WriteLine("連接成功");
        }

        void client_DataReceived(object sender, DataEventArgs e)
        {
            string msg = Encoding.Default.GetString(e.Data);
            MessageBox.Show(msg.ToString());
            Console.WriteLine(msg);
        }

        void client_Closed(object sender, EventArgs e)
        {
            Console.WriteLine("連接斷開");
        }

7、客戶端/服務端發送消息

Client:
string message = "123";
            byte[] data = Encoding.Default.GetBytes(message);
            
            async.Send(data,0,data.Length);

8、其他

服務端接受消息必須要有回車加換行符:\r\n

源碼地址

碼雲地址:https://gitee.com/PErobin/Socket.git

SVN地址:svn://gitee.com/PErobin/Socket


免責聲明!

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



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