。每个 MessageFactory 实例拥有一个随机生成的身份,它使用这个身份来从接收的消息中滤出要发送的消息。
总之,这五个类和接口(Member、MemberManager、Reference、Message 和 MessageFactory)构成了一个用于进行对等点发现的简单框架。当然,还有可以改进的空间。可以很容易地添加一种基于事件的机制,用于向感兴趣的侦听器通知成员的出现或消失。一种用于过滤所接收消息的灵活机制将很有用,但其实现却比较困难。我将这些建议留作读者的作业。
Java对等计算实践:基于IP多播的发现(4)
时间:2010-12-14
Member 类
上面描述的框架的完整源代码太长了,这里就不详细展示了,所以让我们只研究 Member 类的部分代码,因为其中包含了操作的大多数内容。更准确地说,操作发生在两个内部类中:MemberClient 类和 MemberServer 类。
请再次考虑第一个示例。它由一个发送 IP 多播数据报的客户机和一个接收数据报的服务器组成。在本例中(清单 3 和 4),两个单独的应用程序执行这两项功能。P2P 应用程序中的对等点的行为方式既象客户机又象服务器,所以我们的 P2P 应用程序应该同时包含两者才是适合的。
清单 3. MemberClient 类
private
class MemberClient
extends Thread
{
public
void
run()
{
try
{
while (true)
{
try
{
Message message = m_messagefactory.createSendMessage();
Reference reference = message.createReference();
message.writeReference(reference);
message.sync();
byte [] arb = message.getByteArray();
DatagramPacket datagrampacket = new DatagramPacket(arb, arb.length);
datagrampacket.setAddress(m_inetAddress);
datagrampacket.setPort(m_nPort);
MulticastSocket multicastsocket = new MulticastSocket();
multicastsocket.send(datagrampacket);
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
try
{
synchronized (this)
{
wait(m_nPeriod);
}
}
catch (InterruptedException interruptedException)
{
break;
}
}
}
catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
}
Java对等计算实践:基于IP多播的发现(5)
时间:2010-12-14
清单 3 包含了 MemberClient 类的源代码。象清单 1 中的客户机一样,这个客户机创建一个 MulticastSocket 实例并使用它来发送一个 DatagramPacket 实例。DatagramPacket 实例包含一个到发送方对等点的引用,该引用是作为字节数组编码的。只要该对等点还是活动的并在运行,客户机就会每隔一段常规时间来广播这条信息。
清单 4. MemberServer 类
private
class MemberServer
extends Thread
{
public
void
run()
{
try
{
MulticastSocket multicastsocket = new MulticastSocket(m_nPort);
multicastsocket.joinGroup(m_inetAddress);
while (true)
{
Message message = m_messagefactory.createReceiveMessage();
byte [] arb = message.getByteArray();
DatagramPacket datagrampacket = new DatagramPacket(arb, arb.length);
multicastsocket.receive(datagrampacket);
message.sync();
if (m_messagefactory.isMine(message) == false)
{
Reference reference = message.createReference();
message.readReference(reference);
m_membermanager.addReference(reference);
}
}
}
catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
}
MemberServer 类在很多方面类似于清单 2 中的服务器。除了创建必需的代码,使用它从建立的通信(wire)上采集适当的数据报以外,这个服务器还对已编码的引用进行解码、创建消息并将消息传递到 MemberManager 实例进行保管。干得不错。
该 |