导读:
摘 要:分析了P2P基本概念及其基本工作原理,探讨了用JAVA实现p2p网络通信的技术,并用一个实例作了进一步阐述。
关键词:P2P,C/S,JAVA,XML,JDK ,TCP,UDP
一、 前言
P2P(Peer-to-Peer 端到端)模型是与C/S(客户/服务器)模型相对应。基于C/S的用户间通信需要由服务器中转,在C/S中的服务器故障将导致整个网络通信的瘫痪。。而基于P2P的用户间通信则是直接通信,去掉了服务器这一层,带来的显著优点是通信时没有单一的失败点,一个用户的故障不会影响整个P2P网络。本文提供了一种用JAVA实现P2P网络通信的方法。
二、P2P通信的关键技术分析
(一) 信息的传递
1.P2P通信模型
由上图可以看出,在P2P网络中,任意两个端点之间可实现直接通信。在基于C/S的网络中,客户端可以通过向服务器注册来实现彼此之间的定位(获得IP和端口)。对于P2P网络中,是如何实现彼此之间的定位和通信,下面做一阐述。
2.获得网络中可以通信端点的IP和端口
假设有一个端点A,欲和P2P网络中其他端点通信,在通信之前,端点A必须首先把自己的IP和端口通知P2P网络中的其他每一个端点。其他每个端点收到这个信息后,就获得了端点A的IP和端口,随后向端点A反馈自己的IP和端口信息,使端点A也获得P2P网络中每个端点的IP和端口。
这里有两个技术可以完成端点A向其他端点通知其IP和端口的工作,一是广播技术,二是多播技术。
广播技术主要在局域网中使用,在局域网中的每一个端点(主机)都不得不接受并处理一个广播数据包。因此为了避免网络阻塞,路由器均限制广播数据包的通过。所以设计基于互联网的P2P程序不适合采用广播技术。
多播技术是一种允许一个或多个发送者(多播源)发送单一的数据包到多个接收者(一次的,同时的)的网络技术。 多播源把数据包发送到特定多播组,而只有属于该多播组的地址才能接收到数据包。多播可以大大的节省网络带宽,提高了数据传送效率。减少了主干网出现拥塞的可能性。多播组中的端点(主机)可以是在同一个物理网络, 也可以来自不同的物理网络(如果有多播路由器的支持)。因此,多播技术是我们的选择。
在JAVA中,发送和接收多播信息的方法:
发送多播信息需经历步骤
确定发送的具体信息内容
String msg = "Hello";
选用专门为多播指定的D类IP地址(224.0.0.1到239.255.255.255),创建一个多播组
InetAddress group = InetAddress.getByName("228.5.6.7");
使用指定的端口(一般选1024以上的端口号)建立多播套接字
MulticastSocket s = new MulticastSocket(6789);
加入多播组
s.joinGroup(group);
创建一个数据报封装多播信息
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
group, 6789);
发送
s.send(hi);
接收多播信息的步骤
开辟接收缓冲区
byte[] buf = new byte[1000];
创建接收数据报
DatagramPacket recv = new DatagramPacket(buf, buf.length);
接收
s.receive(recv);
注意:以上发送和接收程序在同一个文件中实现,若在不同文件中实现则应分别定义多播套接字并加入多播组。
3.与已知IP和端口的端点通信
在互联网上主要采用TCP和UDP来实现两点之间的通信。采用TCP可可靠传送信息,但花费时间较多;采用UDP可快速传递信息,但不能保证可靠传递。
JAVA实现TCP通信的方法
利用Socket(InetAddress addr, int port)和 Socket(String host, int port),创建客户端套接字,利用ServerSocket(int port)创建服务器端套接字,port端口就是服务器监听连接请求的端口,通过调用accept()返回一个最近创建的Socket对象,该Socket对象绑定了客户程序的IP地址或端口号。通过调用Socket的 getInputStream()方法获得输入流读传送来的信息,也可能通过调用Socket的 getOutputStream()方法获得输出流来发送消息。
JAVA实现UDP通信的方法
使用DatagramPacket(byte [] buffer, int length, InetAddress addr, int port) 确定数据包数组、数组的长度、数据包的地址和端口信息。使用DatagramSocket()创建客户端套接字,而服务器端则采用DatagramSocket(int port),调用send(DatagramPacket dgp)和 receive(DatagramPacket dgp)来发送和接收数据包。本文设计的程序采用UDP。
(二)信息的表示
使用XML技术
XML是以文本数据为基础的非常灵活的格式。在通信过程中,传输的数据虽然可以根据实际需要指定任意格式。但在应用中广泛选择XML,原因是,XML提供了切合实际的并能清楚描述和易于读写的格式。编写XML文件和解析XML文件的工作均容易完成。通过文本编辑器可以用100%的纯ASCII文本来书写XML文件。XML的解析工作既可自己编程来实现,也可以采用多家公司提供的XML解析器。由于XML是一种国际标准,采用XML对于程序将来功能的扩展也可带来很多好处。
(三) 信息的响应
在通信过程中,信息的响应是至关重要的。对于实时通信系统P2P,更看重信息响应的速度。本文所设计的P2P通信程序提高响应速度主要从下面两个方面进行了处理。
1. 队列
由于P2P网络中的端点(主机)通常要接收来自很多端点的信息,如果程序等处理完一个信息后,再接收新的信息,势必会导致某些信息的遗漏。所以接收信息的程序只管把接收到的信息放入队列缓冲,处理信息的程序则从队列中依次取出信息进行处理。
2. 多线程
JAVA中的多线程技术可以使多段程序同时运行。利用多线程技术可以把用户界面、信息接收、信息处理分别处理,使程序更加稳定流畅,大大提高了信息的响应速度。
三、P2P通信程序实例
(一) 功能描述
本程序是一个P2P通信程序,使用此软件的用户可以建立P2P通信网络。网络中的用户之间可以方便地通信。同时,此网络是动态的,换句话说,用户可以随时加入和退出此网络。
主要功能有:
获得P2P网络中端点(主机)的IP,并动态更新
可以向任何已知IP的端点发送文本信息
可以接收其他端点发送的文本信息
可以获得某些端点退出网络的信息
功能在用户界面上的体现
(二) 程序框架
1. 信息流图
信息流图描述了信息的发送和接收过程。事实上,每个端点必须同时具有发送和接收信息的功能,因此,上图的功能将集成在一个用户程序中。
2. 类表
根据信息流图,确定相应的类实现其功能。
(二)程序流图
四、结束语
本程序旨在构建P2P网络通信的基本框架,故程序提供的功能较为简单,如只能交换文本信息,网络套接字端口固定等。读者可以在此基础上扩展其功能,如实现文件传输、动态分配端口等。