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

前段時間,有幾個研究ESFramework網絡通信框架的朋友對我說,ESFramework有點龐大,對於他們目前的項目來講有點「殺雞用牛刀」的意思,由於他們的項目不須要文件傳送、不須要P2P、不存在好友關係、也不存在組廣播、不須要服務器均衡、不須要跨服務器網絡通信、甚至都不須要使用UserID,只要一個客戶端能與服務端進行簡單的穩定高效的C#網絡通訊組件就能夠了。因而,他們建議我,整一個輕量級的C#網絡通訊組件來知足相似他們這種項目的需求。我以爲這個建議是有道理的,因而,花了幾天時間,我將ESFramework的內核抽離出來,通過修改封裝後,造成了StriveEngineC#網絡通訊組件,其最大的特色就是穩定高效、易於使用。經過下面這個簡單的demo,咱們應該就能上手了。文末有demo源碼下載,咱們先上Demo截圖:html

  

1.StriveEngineC#網絡通訊組件Demo簡介

該Demo總共包括三個項目:服務器

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

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

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

StriveEngine 內置支持TCP/UDP、文本協議/二進制協議,該Demo咱們使用TCP、文本格式的消息協議,消息的結束符爲"\0"。ui

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); } }

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

(1)首先調用NetworkEngineFactory的CreateTextTcpServerEngine方法建立引擎(服務端、TCP、Text協議)。編碼

(2)根據須要,預約引擎實例的某些事件(如MessageReceived事件)。spa

(3)調用引擎實例的Initialize方法啓動網絡通信引擎。code

(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源碼及說明

相關文章
相關標籤/搜索