现在我们将在ESFramework Demo -- 文件传送Demo 的基础上,使用ESPlus提供的第四个武器,为其增加P2P通信的功能。在阅读本文之前,请务必先掌握ESFramework 开发手册(04) -- 可靠的P2P 一文中介绍的P2P的基础知识以及相关API的用法。

本Demo主要演示以下功能:

(1)创建基于TCP的P2P通道

(2)创建基于UDP的P2P通道(内部使用可靠的UDP)

(3)使用P2P通道发送消息和传送文件

一.服务端

在P2P打洞的过程中,服务端会参与协助P2P通道的建立,整个过程是由ESFramework/ESPlus内部自动完成的,而这个过程对于框架使用者是透明的。P2P通道创建后,客户端与客户端之间的通信就与服务器没有任何关系了。所以我们直接把上一个demo的服务端拿过来用,不需要做任何修改。

二.客户端

客户端主要使用IRapidPassiveEngine提供的P2PController来查询和控制P2P通道的状态。

尝试创建P2P通道

正如ESFramework 开发手册(04) -- 可靠的P2P 一文中介绍的,并不是所有的客户端之间的P2P通道都可以创建成功,创建P2P通道是一个尝试的过程,IP2PController的P2PConnectAsyn方法就是尝试与目标用户创建P2P通道。

时机很重要。在何时创建P2P通道了?一般而言,是在两个客户端需要高频通信之前,调用P2PConnectAsyn进行尝试创建。

在本Demo中,我们是在每次打开与目标用户的聊天窗口的时候,来尝试创建P2P通道的。如下所示:

  void listView1_MouseDoubleClick(object sender, MouseEventArgs e)  {      if (e.Button != System.Windows.Forms.MouseButtons.Left)      {          return;      }

      ListViewHitTestInfo info = this.listView1.HitTest(e.Location);      if (info.Item != null)      {          //尝试与目标用户建立P2P通道            this.rapidPassiveEngine.P2PController.P2PConnectAsyn(info.Item.Text);

          ChatForm form = this.chatFormManager.GetForm(info.Item.Text);
           ......
       }  } 

使用P2PConnectAsyn方法开始打洞时,若双方位于同一局域网,一般会建立起基于TCP的P2P通道;若双方位于不同的网络,一般会建立起基于UDP的P2P的通道。如果与目标用户之间已经存在可用的P2P通道,则P2PConnectAsyn将不再做任何动作,而直接返回。

为了获得P2P通道创建成功或失败以及后续P2P通道被关闭的通知,demo中我们在MainForm的Initialize方法中预定了P2PController的P2PChannelOpened和P2PChannelClosed事件。

   //预定P2P Channel创建成功的事件   this.rapidPassiveEngine.P2PController.P2PChannelOpened += new CbGeneric<P2PChannelState>(P2PController_P2PChannelOpened);   //预定P2P Channel关闭时的事件   this.rapidPassiveEngine.P2PController.P2PChannelClosed += new CbGeneric<P2PChannelState>(P2PController_P2PChannelClosed);

当P2P通道创建成功或被关闭时,本demo通过修改对应聊天窗口的Title文字来显示这种状态。比如,当P2P通道创建成功时,聊天窗口的Title显示如下:

通常,如果两个客户端位于同一个LAN,或者有一个客户端直接位于Internet上,则它们之间的P2P通道是基于TCP的;否则,创建的P2P通道是基于UDP的。

ChatForm提供了ShowP2PChannelState方法来显示与聊天对象之间的P2P通道状态。

       ///<summary>       /// 显示P2P连接的状态        ///</summary>        public void ShowP2PChannelState(P2PChannelState state)        {            this.Text = (state != null) ? string.Format("正在与{0}对话中【{1}直连:{2}】...", this.friendID, state.ProtocolType, state.DestIPE) : string.Format("正在与{0}对话中...", this.friendID);        } 

请注意,当与目标用户之间没有P2P通道时,P2PController的GetP2PChannelState方法返回的是null。

观察P2P通信

当P2P通道创建成功后,两个用户之间的后续通信将经过P2P通道传送,在本Demo中,表示后续的聊天消息以及文件传送都将通过P2P通道进行。

那么,如何判断消息是通过服务器中转的,还是经过P2P通道直接传送的了?我们常用的有两个简单的方法。

(1)观察服务器的MainServerForm界面。

如果消息是经过服务器中转的,那么界面上显示消息接收者用户对应的“下载次数”、“上传次数”、“最后一次下载时间”等都会跟着发生变化。就本例来说,每当你给对方发送一个聊天消息,如果是经过服务器中转,那么界面上显示的对方的下载次数会增加1,自己的上传次数也增加1,自己的最后一次上传时间也会变化。而如果消息是通过P2P通道传送的,这些数据就不会受影响。

(2)查看资源监视器

如果是Win7的系统,任务管理器“性能”显示中提供了“资源监视器”,可以监控网络的活动。使用它,我们就可以看到应用程序在和哪些机器进行通信。如下图所示:

上面是我们另一个P2P应用demo的截图,图中59.175.145.163是服务器的IP,而我们看到OMCS.ClientDemo.exe接收数据的主要流量来自于ZY-PC这台电脑,这表示两个客户端之间的数据是经过P2P通道传送的,没有通过服务器中转。之所以图中显示的客户端与服务器之间还有微小的流量,那是由类似定时心跳消息等产生的。

如果不是Win7系统,也可以通过安装网络监控软件(如NetLimiter)来查看这些信息。

三.源码下载

ESFramework.Demos.P2P 源码

阅读 更多ESFramework开发手册系列文章。

-----------------------------------------------------------------------------------------------------------------------------------------------

关于ESFramework的任何问题,欢迎联系我们:

电话:027-87638960

Q Q:372841921

邮件:esframework@oraycn.com

转载于:https://www.cnblogs.com/xumaojun/p/8541633.html

ESFramework Demo -- P2P通信Demo(附源码)相关推荐

  1. Babylonjs 最全demo集合 (内附源码)

    Babylonjs 最全demo集合 (内附源码) 为了方便学习Babylonjs引擎,整理了130多个示例,并且所有的例子全部本地化了,可以离线部署.以后会分别讲解. 一.源码模块介绍 Animat ...

  2. 源码系列:基于FPGA的PS2通信电路设计(附源码)

    今天给大侠带来基于FPGA的PS2通信电路设计,附源码,获取源码,请在"FPGA技术江湖"公众号内回复"PS2源码",可获取源码文件.话不多说,上货. 设计背景 ...

  3. 一个快速测试PlayCanvas Demo 的工程(内附源码)

    PlayCanvas Paoject 一个快速测试PlayCanvas Demo 的工程. 源码下载: PlayCanvas Paoject下载地址 操作说明: 1.安装依赖 npm install ...

  4. 客户端服务器通信demo(续) -- 使用二进制协议 (附源码)

    转载连接: http://blog.csdn.net/zhuweisky/article/details/11827797 在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类: ...

  5. Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源码

    转载地址 ; http://blog.csdn.net/hejingyuan6/article/details/46723021 上篇博客我们说spring web Flow与业务结合的方式主要有三种 ...

  6. VC++利用笔记本自带摄像头扫二维码功能(附源码demo)

      VC++开发常用功能一系列文章 (欢迎订阅,持续更新...) 第8章:VC++利用笔记本自带摄像头扫二维码功能(附源码demo) 源代码demo已上传到百度网盘:永久生效  ,代码实现了打开笔记本 ...

  7. java实现高德地图app,Android 高德地图入门demo,最新高德地图实现方法,附源码及apk...

    [实例简介] Android 高德地图入门demo,最新高德地图实现方法,附源码及apk [实例截图] [核心代码] GaoDeDemo ├── GaoDeDemo │   ├── app │   │ ...

  8. 【javaCV基于虹软人脸识别demo添加电脑摄像头人脸识别(图片保存,视频保存,摄像头显示等 )(附源码)】

    javaCV基于虹软人脸识别demo添加电脑摄像头人脸识别(图片保存,视频保存,摄像头显示等 )(附源码) 文章目录 javaCV基于虹软人脸识别demo添加电脑摄像头人脸识别(图片保存,视频保存,摄 ...

  9. DSP:6678开发板NDK网口通信完整实现(附源码)

    如果出现图片打不开,或是显示异常,请点击下方链接阅读原文!!! DSP:6678开发板NDK网口通信完整实现(附源码) - 子木的文章 - 知乎 https://zhuanlan.zhihu.com/ ...

  10. 液晶屏驱动 Realtek2660H方案demo有电路板,电路图源码#Realtek2660H方案

    #Realtek2660H方案demo有电路板,电路图源码#Realtek2660H方案 有电路板,电路图,源码! 有兴趣从事液晶屏驱动的人可入手!走不错的学习资料及平台!无电子开发经验的人慎入!有r ...

最新文章

  1. 多线程读一个全局变量要不要加锁?还是说只是当修改全局变量的时候才要加锁?...
  2. 判断一个矩阵是否可对角化
  3. html怎么做出相框的效果,PS滤镜制作漂亮的实木相框效果
  4. jquery.formValidator表单验证语法
  5. 各执一词,民用安防市场现状看法PK
  6. 什么?吴宗宪在淘宝帮你买买买?
  7. C# 类中索引器的使用
  8. java ee 设计模式解析与应用_Java EE 设计模式解析与应用_IT教程网
  9. Java面试宝典大集锦
  10. 环境化学试题及答案大全
  11. SpringBoot整合WebSocket实现聊天室系统
  12. mysql查询字段最大的一条数据类型_SQL查询一个表中类别字段中Max()最大值对应的记录...
  13. tcp伪报头_TCPUDP伪首部详解
  14. Windows 的应急事件分类-
  15. html+css+js 实现图片轮播效果
  16. 百度竞价推广的十大误区
  17. optimizer.zero_grad()意义
  18. 腾讯面试:《警察抓小偷逻辑题》
  19. AD新建工程快速绘制PCB封装
  20. 【把图片制作成电子书】名编辑电子杂志大师教程 | 导入图片转换成电子杂志

热门文章

  1. 第一周 从C走进C++ 002 命令行参数
  2. 修改centos6.5的时区
  3. web:网站性能工具Yslow
  4. 关于在Winphone中使用Google Map的问题(徐林峰)
  5. 在java中如何把字符串转换成时间格式?
  6. sqlite工作记录-1数据库数据写入-转
  7. IOC 容器中那些鲜为人知的细节(关于 autowiring)
  8. 蓝桥杯 ALGO-86 算法训练 矩阵乘法
  9. PAT 乙级 1014. 福尔摩斯的约会 (20) Java版
  10. 蓝桥杯 BASIC-26 基础练习 报时助手