首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

客户端服务器通讯demo(附源码)

2013-07-01 
客户端服务器通信demo(附源码)前段时间,有几个研究ESFramework的朋友对我说,ESFramework有点庞大,对于他们

客户端服务器通信demo(附源码)

前段时间,有几个研究ESFramework的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送、不需要P2P、不存在好友关系、也不存在组广播、不需要服务器均衡、不需要跨服务器通信、甚至都不需要使用UserID,只要客户端能与服务端进行简单的稳定高效的通信就可以了。于是,他们建议我,整一个轻量级的通信组件来满足类似他们这种项目的需求。我觉得这个建议是有道理的,于是,花了几天时间,我将ESFramework的内核抽离出来,经过修改封装后,形成了StriveEngine,其最大的特点就是稳定高效、易于使用。通过下面这个简单的demo,我们应该就能上手了。文末有demo源码下载,我们先上Demo截图:

  客户端服务器通讯demo(附源码)

1.Demo简介

该Demo总共包括三个项目:

1.StriveEngine.SimpleDemoServer:基于StriveEngine开发的服务端。

2.StriveEngine.SimpleDemoClient:基于StriveEngine开发的客户端。

3.StriveEngine.SimpleDemo:直接基于.NET的Socket开发的客户端,其目的是为了演示:在客户端不使用StriveEngine的情况下,如何与基于StriveEngine的服务端进行通信。

StriveEngine 内置支持TCP/UDP、文本协议/二进制协议,该Demo我们使用TCP、文本格式的消息协议,消息的结束符为"\0"。

2.Demo服务端

客户端服务器通讯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);        }    }
客户端服务器通讯demo(附源码)

关于服务端引擎的使用,主要就以下几点:

(1)首先调用NetworkEngineFactory的CreateTextTcpServerEngine方法创建引擎(服务端、TCP、Text协议)。

(2)根据需要,预定引擎实例的某些事件(如MessageReceived事件)。

(3)调用引擎实例的Initialize方法启动通信引擎。

(4)调用服务端引擎的SendMessageToClient方法,发送消息给客户端。

3.Demo客户端

客户端服务器通讯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);    }
客户端服务器通讯demo(附源码)

关于客户端引擎的使用,与服务端类似:

(1)首先调用NetworkEngineFactory的CreateTextTcpPassiveEngine方法创建引擎(客户端、TCP、Text协议)。

(2)根据需要,预定引擎实例的某些事件(如MessageReceived、ConnectionInterrupted?事件)。

(3)根据需要,设置引擎实例的某些属性(如AutoReconnect属性)。

(4)调用引擎实例的Initialize方法启动通信引擎。

(5)调用客户端引擎的SendMessageToServer方法,发送消息给服务端。

4.基于Socket的客户端

这个客户端直接基于.NET的Socket进行开发,其目演示了:在客户端不使用StriveEngine的情况下(比如客户端是异构系统),如何与基于StriveEngine的服务端进行通信。该客户端只是粗糙地实现了基本目的,很多细节问题都被忽略,像粘包问题、消息重组、掉线检测等等。而这些问题在实际的应用中,是必需要处理的。(StriveEngine中的客户端和服务端引擎都内置解决了这些问题)。
该客户端的代码就不贴了,大家可以在源码中看到。

5.源码下载

? ??Demo源码下载。

?

热点排行