輕量級C#網路通訊元件StriveEngine —— C/S通訊開源demo(附原始碼)

zhuweisky發表於2013-06-17

前段時間,有幾個研究ESFramework網路通訊框架的朋友對我說,ESFramework有點龐大,對於他們目前的專案來說有點“殺雞用牛刀”的意思,因為他們的專案不需要檔案傳送、不需要P2P、不存在好友關係、也不存在組廣播、不需要伺服器均衡、不需要跨伺服器網路通訊、甚至都不需要使用UserID,只要一個客戶端能與服務端進行簡單的穩定高效的C#網路通訊元件就可以了。於是,他們建議我,整一個輕量級的C#網路通訊元件來滿足類似他們這種專案的需求。我覺得這個建議是有道理的,於是,花了幾天時間,我將ESFramework的核心抽離出來,經過修改封裝後,形成了StriveEngineC#網路通訊元件,其最大的特點就是穩定高效、易於使用。通過下面這個簡單的demo,我們應該就能上手了。文末有demo原始碼下載,我們先上Demo截圖:

  

1.StriveEngineC#網路通訊元件Demo簡介

該Demo總共包括三個專案:

1.StriveEngine.SimpleDemoServer:基於StriveEngine開發的服務端。

2.StriveEngine.SimpleDemoClient:基於StriveEngine開發的客戶端。

3.StriveEngine.SimpleDemo:直接基於.NET的Socket開發的客戶端,其目的是為了演示:在客戶端不使用StriveEngine的情況下,如何與基於StriveEngine的服務端進行網路通訊。

StriveEngine 內建支援TCP/UDP、文字協議/二進位制協議,該Demo我們使用TCP、文字格式的訊息協議,訊息的結束符為"\0"。

2.StriveEngineC#網路通訊元件Demo服務端

    private ITcpServerEngine tcpServerEngine;
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            //初始化並啟動服務端引擎(TCP、文字協議)
            this.tcpServerEngine = NetworkEngineFactory.CreateTextTcpServerEngine(int.Parse(this.textBox_port.Text), new DefaultTextContractHelper("\0")); 
       this.tcpServerEngine.ClientCountChanged += new CbDelegate<int>(tcpServerEngine_ClientCountChanged); this.tcpServerEngine.ClientConnected += new CbDelegate<System.Net.IPEndPoint>(tcpServerEngine_ClientConnected); this.tcpServerEngine.ClientDisconnected += new CbDelegate<System.Net.IPEndPoint>(tcpServerEngine_ClientDisconnected); this.tcpServerEngine.MessageReceived += new CbDelegate<IPEndPoint, byte[]>(tcpServerEngine_MessageReceived); this.tcpServerEngine.Initialize(); this.button1.Enabled = false; this.textBox_port.ReadOnly = true; this.button2.Enabled = true; } catch (Exception ee) { MessageBox.Show(ee.Message); } } void tcpServerEngine_MessageReceived(IPEndPoint client, byte[] bMsg) { string msg = System.Text.Encoding.UTF8.GetString(bMsg); //訊息使用UTF-8編碼 msg = msg.Substring(0, msg.Length - 1); //將結束標記"\0"剔除 this.ShowClientMsg(client, msg); } void tcpServerEngine_ClientDisconnected(System.Net.IPEndPoint ipe) { string msg = string.Format("{0} 下線", ipe); this.ShowEvent(msg); } void tcpServerEngine_ClientConnected(System.Net.IPEndPoint ipe) { string msg = string.Format("{0} 上線" ,ipe); this.ShowEvent(msg); } void tcpServerEngine_ClientCountChanged(int count) { this.ShowConnectionCount(count); } private void ShowEvent(string msg) { if (this.InvokeRequired) { this.BeginInvoke(new CbDelegate<string>(this.ShowEvent), msg); } else { this.toolStripLabel_event.Text = msg; } } private void ShowClientMsg(IPEndPoint client, string msg) { if (this.InvokeRequired) { this.BeginInvoke(new CbDelegate<IPEndPoint,string>(this.ShowClientMsg),client, msg); } else { ListViewItem item = new ListViewItem(new string[] { DateTime.Now.ToString(), client.ToString(), msg }); this.listView1.Items.Insert(0, item); } } private void ShowConnectionCount(int clientCount) { if (this.InvokeRequired) { this.BeginInvoke(new CbDelegate<int>(this.ShowConnectionCount), clientCount); } else { this.toolStripLabel_clientCount.Text = "線上數量: " + clientCount.ToString(); } } private void comboBox1_DropDown(object sender, EventArgs e) { List<IPEndPoint> list = this.tcpServerEngine.GetClientList(); this.comboBox1.DataSource = list; } private void button2_Click(object sender, EventArgs e) { try { IPEndPoint client = (IPEndPoint)this.comboBox1.SelectedItem; if (client == null) { MessageBox.Show("沒有選中任何線上客戶端!"); return; } if (!this.tcpServerEngine.IsClientOnline(client)) { MessageBox.Show("目標客戶端不線上!"); return; } string msg = this.textBox_msg.Text + "\0";// "\0" 表示一個訊息的結尾 byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//訊息使用UTF-8編碼 this.tcpServerEngine.SendMessageToClient(client, bMsg); } catch (Exception ee) { MessageBox.Show(ee.Message); } }

關於服務端引擎的使用,主要就以下幾點:

(1)首先呼叫NetworkEngineFactory的CreateTextTcpServerEngine方法建立引擎(服務端、TCP、Text協議)。

(2)根據需要,預定引擎例項的某些事件(如MessageReceived事件)。

(3)呼叫引擎例項的Initialize方法啟動網路通訊引擎。

(4)呼叫服務端引擎的SendMessageToClient方法,傳送訊息給客戶端。

3.StriveEngine C#網路通訊元件Demo客戶端

    private ITcpPassiveEngine tcpPassiveEngine;
    private void button3_Click(object sender, EventArgs e)
    {
        try
        {
            //初始化並啟動客戶端引擎(TCP、文字協議)
            this.tcpPassiveEngine = NetworkEngineFactory.CreateTextTcpPassiveEngine(this.textBox_IP.Text, int.Parse(this.textBox_port.Text), new DefaultTextContractHelper("\0"));
            this.tcpPassiveEngine.MessageReceived += new CbDelegate<System.Net.IPEndPoint, byte[]>(tcpPassiveEngine_MessageReceived);
            this.tcpPassiveEngine.AutoReconnect = true;//啟動掉線自動重連                
            this.tcpPassiveEngine.ConnectionInterrupted += new CbDelegate(tcpPassiveEngine_ConnectionInterrupted);
            this.tcpPassiveEngine.ConnectionRebuildSucceed += new CbDelegate(tcpPassiveEngine_ConnectionRebuildSucceed);
            this.tcpPassiveEngine.Initialize();

            this.button2.Enabled = true;
            this.button3.Enabled = false;
            MessageBox.Show("連線成功!");
        }
        catch (Exception ee)
        {
            MessageBox.Show(ee.Message);
        }
    }

    void tcpPassiveEngine_ConnectionRebuildSucceed()
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new CbDelegate(this.tcpPassiveEngine_ConnectionInterrupted));
        }
        else
        {
            this.button2.Enabled = true;
            MessageBox.Show("重連成功。");
        }
    }

    void tcpPassiveEngine_ConnectionInterrupted()
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new CbDelegate(this.tcpPassiveEngine_ConnectionInterrupted));
        }
        else
        {
            this.button2.Enabled = false;
            MessageBox.Show("您已經掉線。");
        }
    }

    void tcpPassiveEngine_MessageReceived(System.Net.IPEndPoint serverIPE, byte[] bMsg)
    {
        string msg = System.Text.Encoding.UTF8.GetString(bMsg); //訊息使用UTF-8編碼
        msg = msg.Substring(0, msg.Length - 1); //將結束標記"\0"剔除
        this.ShowMessage(msg);
    }       

    private void ShowMessage(string msg)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new CbDelegate<string>(this.ShowMessage), msg);
        }
        else
        {
            ListViewItem item = new ListViewItem(new string[] { DateTime.Now.ToString(), msg });
            this.listView1.Items.Insert(0, item);                
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        string msg = this.textBox_msg.Text + "\0";// "\0" 表示一個訊息的結尾
        byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//訊息使用UTF-8編碼
        this.tcpPassiveEngine.SendMessageToServer(bMsg);
    }

關於客戶端引擎的使用,與服務端類似:

(1)首先呼叫NetworkEngineFactory的CreateTextTcpPassiveEngine方法建立引擎(客戶端、TCP、Text協議)。

(2)根據需要,預定引擎例項的某些事件(如MessageReceived、ConnectionInterrupted 事件)。

(3)根據需要,設定引擎例項的某些屬性(如AutoReconnect屬性)。

(4)呼叫引擎例項的Initialize方法啟動網路通訊引擎。

(5)呼叫客戶端引擎的SendMessageToServer方法,傳送訊息給服務端。

4.基於Socket的客戶端

這個客戶端直接基於.NET的Socket進行開發,其目演示了:在客戶端不使用StriveEngineC#網路通訊元件的情況下(比如客戶端是異構系統),如何與基於StriveEngine的服務端進行網路通訊。該客戶端只是粗糙地實現了基本目的,很多細節問題都被忽略,像粘包問題、訊息重組、掉線檢測等等。而這些問題在實際的應用中,是必需要處理的。(StriveEngineC#網路通訊元件中的客戶端和服務端引擎都內建解決了這些問題)。
該客戶端的程式碼就不貼了,大家可以在原始碼中看到。

5.StriveEngine C#網路通訊元件Demo原始碼下載

    文字協議網路通訊demo原始碼

 

  附相關係列: C#網路通訊元件二進位制網路通訊demo原始碼及說明文件

                        C#網路通訊元件通B/S與C/S網路通訊demo原始碼與說明文件

 另附:簡單即時通訊Demo原始碼及說明

 

版權宣告:本文為博主原創文章,未經博主允許不得轉載。

相關文章