`
jishublog
  • 浏览: 870450 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

5.源码下载

    Demo源码下载。

 

0
5
分享到:
评论

相关推荐

    ICE客户端与服务端通信Demo

    平台编译环境:VS2017 ICE版本:3.7.7 ICEbuilder:5.0.9 ...源码中有两套程序: Server:启动服务器,等待连接 。连接后可双方通信 Client:连接服务器,与服务器通讯。 Slice: 手写几个接口即可。

    Android TCP Socket通信实例Demo源码Apk下载

    本Demo主要实现了安卓(Android)TCP 客户端(Client)和服务器(Server)Demo的Socket通讯。以及对接硬件的项目数据在十六进制&&byte&&int的转换处理。 要注意BufferedReader的readLine()方法的阻塞问题: 读取socket输入...

    STM32单片机作TCP服务器,实现PC多客户端连接Demo

    STM32作TCP服务器,实现PC多客户端连接的模板。本模板是基于正点原子的STM32F750开发板上实现的,多连接处理部分的代码在tcp_server_demo.c中,其他型号型号可参考修改。

    c# .netcore3.1 SignalR Demo源码 实现简易聊天室功能 服务器客户端双向通信 WebScoket

    c# .netcore3.1 SignalR Demo 实现简易聊天室功能,包括用户进入、发送消息、实时接收消息、用户退出、实时查询在线人数, 本项目为SignalIR学习Demo,由本人编写。运行时在浏览器访问http://127.0.0.1:端口号/index...

    基于UDP协议的unity客户端,内涵服务端源码

    基于UDP协议的客户端与服务端通信demo,unity客户端可以不断跟服务端发送信息,内涵服务端的源码

    基于TCP/IP~Android客户端与PC通信源码

    基于TCP~socket,Android客户端与PC通信,客户端源码。已经测试,可用。附带apk,和网络调试助手,方便测试。只需提供服务器的IP和端口号,即可通信。 客户端:一次连接,可发送多次数据。 重点是客户端时时接收...

    蓝牙BLE服务端+客户端.zip

    Android端BLE低功耗开发,扫描设备、连接、通信,DEMO含BLE方式的客户端和服务端,坑与大家共勉

    ESFramework系列Demo源码

    ESFramework系列Demo源码 程序介绍: 本ESFramework系列Demo共有5个Demo。 分别为: 1.ESFramework之入门Demo 2.ESFramework之文件传送Demo 3.ESFramework之P2P通信Demo 4.ESFramework之FTP_Demo 5.ESFramework...

    (源代码)C# Socket服务器和Tcp客户端通信

    最近自己要做Socket通信项目,自己写了Tcp socket通讯的客户端和服务器端通讯demo,希望可以帮到大家

    C Socket通信多线程数据双向收发实例VS2010(全部源码)

    3、实现客户端向服务器端发送不同测试命令,并接收服务器端发送的数据; 4、运用指针上下文实现不同线程的数据共享; 5、实现多个客户端同时连接服务器端; 6、服务器端程序和客户端程序可以运行在同一台计算机,也...

    C++使用SOCKET实现TCP-IP协议的通讯最好的DEMO源码

    那么,那么多的客户端服务器如何区分,你可能会说,根据IP么,不是很完整,很简单的例子,你一台计算机开3个QQ,服务器怎么区分?所以准确的说是IP和端口号,但是客户端的端口号不是由你自己定的,是由计算机自动...

    socket demo局域网通信工具

    局域网通信工具,源码,含客户端和服务器端,pc用,也可以连接手机端。 源码未包含app端

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Tcp服务端与客户端的JAVA实例源代码 2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Tcp服务端与客户端的JAVA实例源代码 2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多...

    vc++ 应用源码包_3

    内含远程控制、进程管理、文件操作、视频控制、注册表操作、客户端服务器端。 redui_src_v0.9.130(DirectUI 3D) DirectUI 3D界面库。 sdk(界面库) RINGSDK包含界面库和图象库。 绘MFC基本控件 PlayerDrectShow...

    C# Socks demo

    用C#写的 用socks 通信的 demo 用vs2010 写的 winform 能客户端发信息到服务器 然后转发 服务器发信息给客户端

    ModBus Tcp 通讯C# +Demo

    C# ModBus Tcp读写数据 与服务器进行通讯,内包含客户端和服务端源码。

    WebSocket.rar Android java-webSocket完整案例源码,推送,即时通信,双向通信,心跳重连

    java-webSocket是免费的,集成java-webSocket开源而成的一个比较完整的demo,实现了客户端向服务端发送消息,以及接收...适用于需要双方相互主动互发消息,推送,以及客户端与客户端通信(此时服务器只做中转)等场景。

    vc++ 应用源码包_1

    内含远程控制、进程管理、文件操作、视频控制、注册表操作、客户端服务器端。 redui_src_v0.9.130(DirectUI 3D) DirectUI 3D界面库。 sdk(界面库) RINGSDK包含界面库和图象库。 绘MFC基本控件 PlayerDrectShow...

    vc++ 应用源码包_2

    内含远程控制、进程管理、文件操作、视频控制、注册表操作、客户端服务器端。 redui_src_v0.9.130(DirectUI 3D) DirectUI 3D界面库。 sdk(界面库) RINGSDK包含界面库和图象库。 绘MFC基本控件 PlayerDrectShow...

Global site tag (gtag.js) - Google Analytics