輕量級C#網絡通信組件StriveEngine —— C/S通信開源demo(附源碼)


前段時間,有幾個研究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源碼及說明

 

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


免責聲明!

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



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