当前页面位置: » 丰搜网 » 文档中心 » 详细内容
peer-to-peer sockets 工程入门
peer-to-peer sockets 工程入门作者:brad neuberg译者:gracepig zhangchi_xjtu@yahoo.com.cn版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:
brad neuberg ;gracepig
原文地址:
http://www.on
java.com/pub/a/on
java/2003/12/03/
p2psockets.
html中文地址:
http://www.matrix.org.cn/resource/article/43/43854_peer-to-peer-
sockets.
html关键词: peer-to-peer
sockets
peer-to-peer (
p2p)
sockets工程在jxta peer-to-peer虚拟网络重新实现了对应于标准tcp/ip网络中的
java标准的
socket,server
socket,和
.netaddress等类。该工程同时还引入了一些注入jetty
web server,apache
xml-rpc客户端和
服务器库,apache j
asper
jsp引擎之类的流行
web package。使这些服务可以运行在peer-to-peer
sockets 的
框架下。
在这片文章结束的时候,你会理解对
p2p sockets packages的需求和以及开发它的动机,学会怎么配置
p2p socket 库使之在你的系统上能够运行,学会怎么样建立
p2p的
服务器和客户端
socket,怎么使用
p2p的
.netaddress 类,还包括
框架下的
安全问题以及它的局限性。
动机p2p socket工程的设计的使用对象是对以下几个领域有兴趣的开发者:
●将inte
.net回归到end-to-end的原则当中
●一种绕过icann和verisign的替代peer-to-peer域名系统,这个系统是完全分布式的,对更新拥有比标准dns快的多的响应速度。
●一种任何人都可以建立活着使用网络服务的inte
.net,及时他们使用动态的ip地址或是没有ip地址,或是只有内网地址(nat),或者是在isp的防火墙之后。
●一个每一个peer都能够自动的建立一个
web server,提供
xml-rpc服务,能够快速的将这种服务提供给其他的peer。
●使为peer-to-peer网络添加
java socket和server
socket 的应用更加容易
●享受更酷的科技
p2p socket 工程在jxta peer-to-peer网络上重新实现了标准
java.net报当中的类。一些人可能要问“难道标准tcp/ip
socket和server
socket不是已经是peer-to-peer的了吗?”标准的tcp/ip
socket和server
socket在理论上是peer-to-peer的,不过由于防火墙,nat设备,以及dns所存在的政治或是技术的问题,在实际上却没有做到这一点。首先,inte
.net上的许多peer使用的都是通过dhcp协议取得的动态ip,这些ip由通过nat设备共享和过滤,还有一些ip地址由于防火墙的限制,很难被访问到。在这样的条件下建立server
socket应用要么是不可能的,要么就需要在应用层进行精妙的控制来绕过这些限制。其次,tcp/ip
socket依赖于dns系统来将用户友好的主机名转变为ip地址。dns在理论上就是办分布式的,但是在管理层面上,dns是在icann下集中式管理的,而icann是一个反应迟钝的,没有创新意识的组织。再次,标准的dns对对那些过滤或是使用动态ip地址的edge-peer支持的并不好,更新需要花费很长的时间传播下去而且并不提供presence信息。对那些想要开发能够扩展dns到新的领域(例如将即时消息的用户名和存在信息加入到dns)的新应用的开发者来说,dns系统的技术和政治因素阻碍了他们的工作。
jxta是一个用于在tcp/ip之上建立peer-to-peer覆盖网络的
开源工程。在网络中的没一个peer都会被分配到一个和ip地址类似的号码,即时他们没有固定的ip地址或是出在防火墙之后。在jxta 网络上的super-peer通讯运行应用层的路由协议来储存例如如果到达其他的peer,如何加入peer group,其他peer提供了怎么样的内容之类的信息。jxta应用层在peer之间提供了中继的代理服务,是出在防火墙或是nat后的peer可以正常的通信。peer可以自己组织成为peer group,这样可以将所有的查询请求限定在natural security container当中。任何peer都可以分布式的建立并发布一个peer group,其他的peer通过使用其他的super-peer可以搜索并发现这些peer group。peer之间的通信通过pipe的方式来进行,这和
unix系统当中的pipe非常的类似。pipe是对两个peer之间通讯方式的一种抽象,它帮助peer互相通讯,即使他们处在不同的网络区域当中。
jxta是一种非常强大的
框架。但是,它并不是一种容易学习的
框架,将现有的软件移植到jxta下也不是一件容易的事情。
p2p sockets成功地将jxta隐藏起来,使之看起来就像是传统的tcp/ip网络。如果peer想要成为
服务器,他只需要简单的使用包含他们想使用的domain name和端口的
p2p server
socket就可以了。
p2p的客户端可以通过host名和特定的端口号来建立
socket连接访问那些服务。host可以被解析为域名,例如www.nike.laborpolicy,或是ip地址,例如44.22.33.22。在这些场景之后,host实际被解析为jxta原语,而不是被解析为dns或是tcp/ip。举例来说:域名www.nike.laborpolicy实际上是jxta peer group 的广告消息中的一个name字段。
p2p sockets和server
socket 与正常的tcp/ip
socket和server
socket的使用方法完全相同。我们为希望了解内幕和那些已经懂得jxta的用户提供了一张表(http://www.on
java.com/on
java/2003/12/03/examples/table.
html),在这张表中可以查询到传统tcp/ip概念上的域名,ip地址等概念和jxta中对等概念的对应关系。
使用这种方式的好处是多方面的。首先,程序员可以将他们在标准tcp/ip
socket和server
socket的知识应用到jxta peer-to-peer网络当中而不需要专门学习jxta。其次,所有的
p2p socket 的代码都是标准
java.net中类的子类,例如
java.net.
socket,所以现存的网络应用可以很容易的移植到peer-to-peer网络当中。
p2p socket工程已经将很多现存的软件移植到了peer-to-peer网络当中,其中包括
web服务器(jetty),它可以接收请求,被在peer-to-peer 网络上提供内容服务;一个
servlet和
jsp引擎(jetty 和
jsper),它可以使现存的
servlet和
jsp直接在
p2p网络中应用;一个
xml-rpc客户端和
服务器(apache
xml-rpc),它可以访问和对外提供
p2p xml-rpc 端点;一个http/1.1客户端(apache commons http-client),它可以访问
p2p的
web 服务器;一个网关(smart cache),它可以是现有浏览器访问
p2p的
p2p web 站点;和wikiwiki(
jspwiki),它能够在你的主机上建立wiki站点,使其他的peer可以通过
p2p网络访问,并编辑。所有的这些软件在移植之后都能够正常的使用并且和以前看起来完全一样。
p2p socket的抽象非常的成功,移植这些软件所花费的时间仅仅是30分钟到几个小时不等。
p2p socket工程是完全
开源的,大部分都采用bsd-type证书,由于是使用
java编写的,所以也具有跨平台的特性。
由于
p2p socket是建立在jxta之上的,所以它可以很容易的处理一些传统的server
socket和
socket所不能处理的情况。第一,在
p2p socket上建立的server
socket,具有fail-over(不知道怎么翻译,应该是可靠性之类的意思)和易扩展的特性。如果不同的peer可以启动server
socket使用同一个域名和端口,例如www.nike.laborpolicy 端口号:80。当一个客户端打开
p2p socket连接到www.nike.laborpolicy 端口号:80时,它会随机的连接到一个提供一个使用这个域名和端口的主机上。所有的这些
服务器peer可能提供同样的
web页面,这就是可以将用户的请求分布到不同的
服务器之上同时也就使得某一个
服务器的崩溃更容易被恢复。这一点和dns round-robin非常的相似,在dns round-robin当中一个域名可以被解析为多个ip地址用来进行负载均衡。第二,由于
p2p socket并不使用dns系统,主机名可以任意指定。用户可以建立他自己的个性结尾,例如www.boobah.cat 或是www.cynthia.goddess,或是应用确定的名字,例如一个即使消息系统使用brad gnuberg或是fidget666当作域名。第三,一个指定域名的服务端口可以分布在全世界很多的peer当中。举例来说,假设你有一个虚拟主机名www.nike.laborpolicy,一个peer可以在80端口提供
web页面,另一个peer可以使用2000端口提供即时消息,最后一个peer可以在3000端口为其他peer提供即时的rss更新。现在一个域名可以由很多分布不同的peer协同在一起提供服务。
需求与配置要开发和使用
p2p socket你必须下载和安装一下的这些软件。
●jdk 1.4+
p2p socket只能工作在jdk 1.4或是更新版本的
java虚拟机之上,由于
p2p socket是
java.net.
.netaddress的子类,在1.4之前,这个类是final类型的。
●
ant 1.5.3+
用来构建和运行
p2p socket以及类似于jetty 和 j
asper之类的扩展
●
p2psockets-1.0-beta1.zip
p2p socket 的最新发布包
安装和配置好jdk和
ant,并保证它们都可以在命令行下正确运行。将
p2psockets-1.0-beta1.zip解开到硬盘上。在目录名当中不能出现空格,否则
p2p sockets的构建文件不能正常工作。
必须将jar文件
p2psockets/lib/
ant-contrib-0.5.jar加入到你的classpath当中去。在windows当中可以使用下面这个命令:
set classpath=%classpath%;c:\p2psockets\lib\ant-contrib-0.5.jarp2p sockets的目录包含两个不同的子目录,test/clientpeer和test/serverpeer,它们中有已经设置好的jxta配置信息(分别在test/clientpeer/.jxta和test/serverpeer/.jxta当中)。如果你想要了解更多的关于jxta的配置问题,你可以阅读jxta配置指南。两个
测试peer已经被配置为最差的情况下工作
模式,也就是peer处在防火墙或是nat设备之后,也就是说用户必须使用其他的中间peer来中继它们的请求。如果用户不处在这种环境下,这种配置方式也是可以工作的。使用jxta的一个好处就是,当你在使用这个系统的时候,它对你的程序几乎是透明的。
当你在
测试本文中的代码的时候,你必须连接到inte
.net。这样做基于一下的两个原因:首先,例子程序使用sun提供的公共jxta
服务器来将启动peer引入jxta网络当中;其次,在一些
操作系统上(例如
windows xp, 缺省),网络系统在你没有连接到网络上时会自动关闭,这样就会阻碍运行在同一个主机上的客户端peer和
服务器peer互相通讯。
建立一个p2p server socket建立一个
p2p server
socket的方法和建立一个标准的
java.net.server
socket完全一样。
// start a server socket for the domain
// "www.nike.laborpolicy" on port 100
java.net.serversocket server = new java.net.p2pserversocket("www.nike.laborpolicy", 100);
通过上面的这种方法,我们可以建立一个server
socket在域名www.nike.laborpolicy 端口100上监听客户端请求。在这种情况下,
p2pserver
socket的代码将会去搜索一个名字叫做www.nike.laborpolicy的peer group。一旦它找到了这个peer group,它会加入;接着它会创建并发布一个jxta peer group 的广告消息在当中会有一个依照特定格式的name域。这个域使用hostname/ip address,例如 www.nike.laborpolicy/44.33.67.22这种格式。我们使用通配符来搜索基于jxta rendezvous
服务器上的主机名或是ip地址,例如www.nike.laborpolicy/*来进行在不知道ip地址情况下的搜索,或是采用*/44.33.67.22来进行指定ip地址的搜索。一旦我们找到或是创建了这个peer group,我们就可以发布这个jxta pipe advertisement到这个peer group当中去,在这个广告信息当中使用name字段设置端口,例如<name>80</name>。
在建立了这个server
socket以后,用户可以像使用普通的
java.net.server
socket一样的使用,等待一个客户端的请求,并获得inputstream或是outputstream来进行通讯:
java.net.socket client = server.accept();
// now communicate with this client
java.io.datainputstream in = new datainputstream(client.getinputstream());
java.io.dataoutputstream out = new dataoutputstream(client.getoutputstream());
out.writeutf("hello client world!");
string results = in.readutf();
system.out.println(results);
尽管客户端看起来和正常的
java.net.
socket很相似,但实际上它已经是通过jxta peer-to-peer网络来进行通讯了,请求与响应消息都是通过其他的peer进行中继来穿越nat和网络区域的。当然,这一些都是隐藏在后台的。
与普通的server
socket不同,我们需要初始化并登录进入我们的peer-to-peer网络。在我们建立
p2pserver
socket之前,我们需要进行以下的操作:
// sign into the peer-to-peer.network, using
// the username "serverpeer", the password "serverpeerpassword",
// and create/find a scoped peer-to-peer.network named "tes.network"
java.net.p2.network.signin("serverpeer", "serverpeerpassword", "tes.network");
头两个参数是用来登录进入peer-to-peer网络的用户名和密码。这是在用户设置jxta configurator的时候的时候输入的,一个
swing的对话框(在第一运行jxta 平台的时候会弹出)会允许你在
p2p 网络上配置你的peer。在你自己的应用当中,你可以从命令行和
gui的方式获取这些值。
p2p sockets 包里面预先配置好了两个jxta peer分别放在test/clientpeer和test/serverpeer下面。
最后的一个参数(上面例子中的tes
.network)是你的peer-to-peer网络的唯一名字。建立在
p2p sockets之上的不同peer-to-peer网络可以在不知道对方存在的情况下共存。客户端和
服务器在特定的peer-to-peer网络当中创建和解析它们的server
sockets和
sockets。最后的一个参数就是你私有的,由应用指定的peer-to-peer网络。如果你创建了一个名叫tes
.network的server
socket而另一个用户登录进入一个名叫inst
antmessagin
.network的server
socket,它们就不能找到对方并进行通讯。
接下来我们来看看p2
.network这个类是怎样工作的。当你调用signin方法的时候,网络字符串(例子中的tes
.network)将会被哈希为一个md5的peer group id;这样就会保证在我们以peer id搜索的时候,这个应用的名字是全局唯一的。所有的域名和ip地址解析都发生在这个应用的peer group内部。应当注意到在test/clientpeer和test/serverpeer当中使用的jxta配置文件都将使用sun rendezvous
服务器作为加入jxta网络的引导
服务器;当你想要使用其他的初始
服务器时,你需要修改配置文件。
对于程序员来说,你可以根据自己的应用或是所创建网络的类型选择自己的网络名,例如:myapplication
.network 或是 acmecompanyinformatio
.network。
最终的代码如下所示:
import java.io.inputstream;
import java.io.outputstream;
import java.io.dataoutputstream;
import java.io.datainputstream;
import java.net.socket;
import java.net.serversocket;
import java.net.p2pserversocket;
import java.net.p2.network;
public class exampleserversocket {
public static void main(string args[]) {
try {
// sign into the peer-to-peer.network,
// using the username "serverpeer", the password "serverpeerpassword",
// and create/find a scoped peer-to-peer.network named "tes.network"
system.out.println("signing into the p2p.network...");
p2.network.signin("serverpeer", "serverpeerpassword", "tes.network");
// start a server socket for the domain
// "www.nike.laborpolicy" on port 100
system.out.println("creating server socket for " + "www.nike.laborpolicy:100...");
serversocket server = new p2pserversocket("www.nike.laborpolicy", 100);
// wait for a client
system.out.println("waiting for client...");
socket client = server.accept();
system.out.println("client accepted.");
// now communicate with this client
datainputstream in = new datainputstream(client.getinputstream());
dataoutputstream out = new dataoutputstream(client.getoutputstream());
out.writeutf("hello client world!");
string results = in.readutf();
system.out.println("message from client: " + results);
// shut everything down!
client.close();
server.close();
}
catch (exception e) {
e.printstacktrace();
system.exit(1);
}
}
}
使用p2p socket来连接p2p server socket建立和使用
p2p socket连接
p2p server
socket一样容易:
首先,需要登录进去指定的peer-to-peer网络当中:
// sign into the peer-to-peer.network,
// using the username "clientpeer", the password "clientpeerpassword",
// and find the peer-to-peer.network named "tes.network"
java.net.p2.network.signin("clientpeer", "clientpeerpassword", "tes.network");
接下来,使用指定的主机名和端口号创建你想要连接的
socket:
java.io.datainputstream in = new datainputstream(socket.getinputstream());
java.io.dataoutputstream out = new dataoutputstream(socket.getoutputstream());
string results = in.readutf();
system.out.println(results);
out.writeutf("hello server world!");
下面是完整的代码:
import java.io.inputstream;
import java.io.outputstream;
import java.io.dataoutputstream;
import java.io.datainputstream;
import java.net.socket;
import java.net.p2psocket;
import java.net.p2.network;
public class exampleclientsocket {
public static void main(string args[]) {
try {
// sign into the peer-to-peer.network,
// using the username "clientpeer", the password "clientpeerpassword",
// and find a.network named "tes.network"
system.out.println("signing into the p2p.network..");
p2.network.signin("clientpeer", "clientpeerpassword", "tes.network");
// create a socket to connect to the
// domain "www.nike.laborpolicy" on port 100
system.out.println("connecting to server socket! at " + "www.nike.laborpolicy:100...");
socket socket = new p2psocket("www.nike.laborpolicy", 100);
system.out.println("connected.");
// now communicate with this server
datainputstream in = new datainputstream(socket.getinputstream());
dataoutputstream out = new dataoutputstream(socket.getoutputstream());
string results = in.readutf();
system.out.println("message from server: " + results);
out.writeutf("hello server world!");
// shut everything down
socket.close();
}
catch (exception e) {
e.printstacktrace();
system.exit(1);
}
}
}
运行p2p server socket和socket的例子打开两个不同的shell 窗口。在两个窗口当中,键入下面的命令来设置使用
ant构建所需的环境变量(修改环境变量使之指向你安装
p2p sockets和jdk的位置):
set p2psockets_home=c:\p2psockets
set java_home=c:\j2sdk1.4.1在两个窗口中,都进入
p2psockets的目录,例子源码在
p2psockets/src/examples目录下面,名字分别叫做exampleclient
socket.
java和exampleserver
socket.
java。所有的代码都已经编译进入
p2psockets/dist/examples目录当中去,但是如果你想要重新编译它们的时候,在其中一个shell当中使用下面的这个命令:
ant clobber build jar要运行客户端和
服务器,在一个窗口当中键入下面的命令来启动例子
p2p server
socket:
ant example-serversocket-run你会看到如下的屏幕显示:
buildfile: build.xml
example-serversocket-run:
signing into the p2p.network...
using the application peer group name tes.network
waiting for rendezvous connection.........
finished connecting to rendezvous.
creating server socket for
www.nike.laborpolicy:100...
waiting for client...在另一个窗口当中,输入如下的命令启动
p2p client
socket:
ant example-clientsocket-run你会在client peer 的窗口当中看到如下的输出:
buildfile: build.xml
example-clientsocket-run:
signing into the p2p.network..
using the application peer group name tes.network
waiting for rendezvous connection......
finished connecting to rendezvous.
connecting to server socket at
www.nike.laborpolicy:100...
connected.
message from server: hello client world!在
服务器窗口,你会看到如下的输出:
buildfile: build.xml
example-serversocket-run:
signing into the p2p.network...
using the application peer group name tes.network
waiting for rendezvous connection.........
finished connecting to rendezvous.
creating server socket for
www.nike.laborpolicy:100...
waiting for client...
client accepted.
message from client: hello server world!祝贺你,你已经建立了一个简单的peer-to-peer网络,这并没有需要你做太多的工作,也没有需要你在基本的
java sockets和server
sockets以外的知识。
如果你遇到困难,首先确保你已经连接到互联网上,是否使用
java 1.4+,确保
p2p socket package 所安装的目录名当中没有空格。也许你根据你所使用的特殊网络环境调整你的jxta网络设置。如果你想要在两个被nat所阻塞的不同的机器上运行客户端和
服务器socket例子,也许你是碰到了
p2p sockets所公开的一个bug。
检查一个主机名,ip地址,或是端口号是否被占用缺省情况下,
p2p.netaddress和
p2pserver
socket类并不会去检查主机名,ip地址,或是端口号是否被占用。这样做的原因是应用的开发者可以使用独一无二的方法来使用
p2p server
socket而传统的
socket是不能这样做的。举例来说,不同的peer可以启动
p2p server
sockets使用同一个主机名和端口,通过这种方式来提供容错性和扩展性。如果我们想要在发现地址已经被占用的时候抛出一个异常的话,这种可能行就被排除了。
尽管如此,系统提供了用于发现主机名,ip地址或是端口号是否被占用的方法。这些是
java.net.
p2pnameservice当中的静态方法。例子如下:
boolean nameavailable = p2pnameservice.ishostnametaken("www.nike.laborpolicy");
boolean portavailable = p2pnameservice.isporttaken("www.nike.laborpolicy", 80);
boolean addressavailable = p2pnameservice.isipaddresstaken("33.44.74.12");
在你需要为你的server创建一个唯一的实例的时候可以在创建
p2p server
socket之前调用这些方法。(请阅读局限性和
安全问题一章,在
p2p的域名欺骗)
你已经了解到不少关于
p2p socket和server
socket的东西。接下来的这一章将会介绍如果使用
p2p sockets包所提供的其他与标准tcp/ip兼容的类的技术细节。你并不是一定需要了解这些内容,但如果你了解,你可以使用这些
.netaddress类,本地环回地址(127.0.0.1)或是任播地址(0.0.0.0)。如果你跨过下面的章节,请确保你阅读了文章末尾处局限性和
安全问题那一章。
使用p2p .netaddress 类p2p sockets 包中包含了对于
java.net.
.netaddress的一个子类实现。
下面的例子介绍了几种不同的方法,用来创建一个
p2p.netaddress对象。
// create an .netaddress where we know the host
// name but not the ip address.
// this will not search the.network to find the
// corresponding ip address.
.netaddress .netaddr = p2p.netaddress.getbyaddress("www.nike.laborpolicy", null);
// create an .netaddress where we know the ip
// address but not the host name.
// this will not search the.network to find the
// corresponding host name.
.netaddress .netaddr = p2p.netaddress.getbyaddress("55.32.77.34", null);
// create an .netaddress where we know both the
// ip address and the host name.
// no searching will occur on the.network
byte ipaddress[] = new byte[4];
ipaddress[0] = 55;
ipaddress[1] = 32;
ipaddress[2] = 77;
ipaddress[3] = 34;
.netaddress .netaddr = p2p.netaddress.getbyaddress("www.nike.laborpolicy", ipaddress);
// create an .netaddress object using the hostname.
// the.network will be searched for the corresponding ip address
.netaddress .netaddr = p2p.netaddress.getbyname("www.boobah.cat");
// create an .netaddress object using the hostname.
// the.network will be searched for the corresponding ip address
.netaddress .netaddress[] = p2p.netaddress.getallbyname("www.boobah.cat");
// create an .netaddress object using the ip address.
// the.network will be searched for the corresponding host name
byte ipaddress[] = new byte[4];
ipaddress[0] = 55;
ipaddress[1] = 32;
ipaddress[2] = 77;
ipaddress[3] = 34;
.netaddress .netaddr = p2p.netaddress.getbyaddress(ipaddress);
// get the host name and ip address for the local host
.netaddress .netaddr = p2p.netaddress.getlocalhost();
一旦你创建了一个一个
p2p.netaddress对象,你就可以像使用一个正常的
.netaddress对象那样使用它:
.netaddress .netaddr = p2p.netaddress.getbyname("www.boobah.cat");
string hostname = .netaddr.gethostname();
string ipaddressstring = .netaddr.gethostaddress();
byte ipaddress[] = .netaddr.getaddress();
boolean islocalhost = .netaddr.isloopbackaddress();
p2p server
sockets相比起标准的server
socket来说,拥有一个有趣的问题。由于
p2p sockets系统自己实现了一个简单的dns system,我们需要一种方法来建立一个
.netaddress对象,即使此时主机名还并不存在;明确的一点是我们并不想搜索整个网络来将给定的主机名解析为ip地址,反之亦然,也是由于二者可能都不存在。我们可能会使用
.netaddress对象来将一个
p2pserver
socket绑定到一个新的主机名和ip地址上。
p2p sockets目前重载了标准的getbyaddress(string host,byte address[])方法来避免对没有给定的信息解析。由于对于这种信息的解析是没有意思而且是不必要的,所以这种方法在创建一个
p2p.netaddress的对象时是值得推荐的。要检查指定的主机名或是ip地址是否已经被占用,可以使用
p2pnameservice类的方法,具体的使用方法在上一章已经介绍过了。
.netaddress对象可以再启动
p2p sockets和server
sockets时使用,就和使用标准的
java sockets和server
sockets一样:
.netaddress .netaddr = p2p.netaddress.getbyaddress("www.boobah.cat", null);
serversocket server = new p2pserversocket(.netaddr, 80);
.......
.......
.......
.netaddress .netaddr = p2p.netaddress.getbyaddress("www.boobah.cat", null);
socket server = new p2psocket(.netaddr, 80);
本地环回(127.0.0.1)地址和任播地址(0.0.0.0)p2p sockets包提供了一个广播地址的简单实现,这个地址就是0.0.0.0。在标准的tcp/ip server
sockets使用方法当中,对于广播的接口是这样介绍的“对于本机上任意一个可用的ip地址启动server
socket;不需要知道这个ip地址具体是什么。”在
p2p server
sockets的环境当中,一个主机不能是“multi-home”的,也就是说,就是不能有多余一个的ip地址。取而代之的是,server
socket会被指定一个自动生成的主机名,也就是它的jxta peer名。举例来说,如果一个peer的名字叫做bradgnuberg,这个peer被给定了一个自动生成的主机名www.bradgnuberg.peer。 缺省状况下,前缀是“www.”,后缀是“.peer”。这些值目前是不能自定义的,但在未来的版本当中会给出这种能力。
我们使用自动生成的peer名来解析广播和环回地址:
// in the following example, assume the peer's
// local jxta name is bradgnuberg.
.netaddress .netaddr = p2p.netaddress.getlocalhost();
serversocket socket = new p2pserversocket(.netaddr, 100);
// returns "www.bradgnuberg.peer"
string hostname = socket.gethostname();
在这段代码运行之前,你必须在localhost和指定端口上启动一个
p2pserver
socket。
p2p server
socket同样提供和标准server
sockets相兼容的另一种特性,尽管这个特性可能很少会被使用。标准的tcp/ip server
socket可以在不指定端口的情况下被启动。这种情况下会启动一个server
socket使用随机的“私有”端口about 1024(不知道什么意思)。
p2psocket同样支持了这个功能;如果你启动一个server
socket而没有指定主机名,广播接口,或是端口号,一个随机的端口号会在1024和65535之间产生。你可以从server
socket上获得这个端口号,然后使用其他的途径通知客户端
socket,告诉它一个私有的,随机的端口好已经可以使用了。
局限性和安全问题p2p sockets 工程目前有一下的局限性和
安全问题:
●假冒主机名和ip地址的情况在peer当中比较少见,所以现在还没有一种机制用于将指定的主机名和ip地址
安全的联系到特定peer或是peer group上。
●网络容易收到dos(denial-of-service)攻击,当一个peer在网络中大量发送请求或是不断的建立server
sockets。
●
p2p socket 报还没有被绑定到jvm security manager architecture(jvm
安全管理架构)当中,在这个
框架之中代码会被根据
安全策略放到沙箱之中。一旦一个peer被暴露在网络当中,其他的peer可以利用
java虚拟机的缺陷或是
p2p socket层本身的缺陷来危及这个peer的
安全。将peer的代码放到沙箱里面和本地机器的资源格离起来可以保护这个缺陷,但由于
p2p socket在执行之前并不检查
安全管理,所以目前这种方法还不可行。将
jsp引擎包含在标准的个人电脑上,例如
jsp依赖于
javac,
java编译器上同样是很危险的。将网络路径包含在一种语言的编译器当中也很危险,这是一种攻击计算机取得更高的访问权的常用方式。你应该预先编译好你的
jsp和
servlet,并将它们绑定到你的peer程序当中而不是提供整个的
jsp引擎。
●还不支持多播ip地址和多播
socket。
●还不支持udp
socket。
●一些
socket选项,流入solinger,并没有被支持。
●不支持非阻塞的i/o
socket 管道
●本机的环回
socket服务器被暴露给外界,这是不对的。
●不支持ssl/https
●jxta的配置器在没有jxta配置的时候会被激活。这带来了几个问题。首先,这是
p2p sockets暴露给程序员jxta概念的最后一个地方,其次,它要求用户深入了解这个配置系统以查找出他是否处在防火墙或是nat设备之后。未来的工程会自动配置这些属性,加入一种“内省”的方法,来自我感知是否处在防火墙或是nat设备之后。
版权信息:
p2p socket,包括本文的源代码,都受sun project jxta software license的保护。
资源:
●"how to create peer-to-peer
web servers,
servlets,
jsps, and
xml-rpc clients and servers"
●
p2p sockets主页
●jxta主页
●jxta配置器
●"what is a wikiwiki?"
●jdk 1.4
●
ant 1.5.3
●
p2psockets-1.0-beta1.zip
●brad gnuberg的
weblog
●给brad gnuberg发邮件
问题?评论?请查阅
p2p sockets homepage或和作者brad neuberg联系。或在太平洋标准时间,从周一到周五拨打1(510) 938-3263。或者查看他的网志,www.codinginparadise.org,获得关于mozilla,
java,jxta和
p2p的新闻。
brad neuberg是一个
开源开发者,目前居住在san francisco