服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

java联网增强技术


  java联网增强技术
  
         
  
  ――研究j2se1.4中最新的联网特姓
  
  作者:john zukowski 本文选自:ibm dw中国 2003年05月20日
  
    随着 merlin 的发布,java.net 包发生了很大的变化。不仅添加了六个类和三个异常,而且现有的类中有许多都进行了更改以支持额外的功能(比如改进 url 编码和解码)。在本文中,john zukowski 向您说明了用 java 技术进行联网有什么新鲜和不同之处,其中包括 j2se 1.4 中最新的联网功能:ipv6 支持、uri、网络接口、安全套接字和非绑定套接字。
  
    java 编程中的联网包括了定位和识别资源的能力以及通过 tcp 和 udp 连接进行通信的能力。首先,您需要识别具有象 www.ibm.com 这样名称的资源,然后打开到该资源的连接,最后在您自己和连接的另一端之间发送信息包。由于安全姓原因,可能会包括其它任务,但是整个过程是一样的。对于 java 平台,会在 java.net 包中找到支持这些操作的类。从 java 编程的早期到现在,这些操作中大多数都未曾发生太大的变化。但是,随着 merlin 的发展,这些基本操作中有些已经作了改进,以支持有价值的新功能。在本文中,我们将研究五个此类功能:ipv6 支持、uri、网络接口、非绑定套接字和安全套接字。
  
  对 ipv6 地址的支持
  
    首先让我们研究一下对下一代因特网协议 v6(internet protocol v6,ipv6)寻址体系结构的新支持。借助于 inetaddress 的两个新子类(inet4address 和 inet6address),您能够与基于 tcp 和 udp 的应用程序进行连接。inet4address 支持大多数机器所支持的较旧的(而且通常是唯一的)ip 寻址样式,localhost 的格式为 127.0.0.1。rfc2373(请参阅参考资料)中所定义的新寻址方案提供了一种用冒号隔开的格式,其中 0:0:0:0:0:0:0:1 是与 127.0.0.1 等价的回送地址。新的类允许应用程序支持一种或这两种寻址方案。
  
    对 ipv6 的支持取决于底层平台是否支持它,solaris 8 和更高版本,以及 linux 2.1.2 和更高(redhat 6.1+)版本都支持 ipv6,而 microsoft windows 并不支持它(microsoft 的 window 2000 实现是个有限的实现)。希望 j2se 1.4 的 windows 版本以后能支持 ipv6。
  
    认识统一资源标识符
  
    java.net 包现已包括了统一资源标识符(uniform resource identifier,uri)类。可将 uri 看作是幕后没有协议处理程序的统一资源定位符(uniform resource locator,url)。通常,url 看上去象 http://www.ibm.com。为了使 java 语言运行时理解 url,它需要知道该怎么处理以 http: 开头的信息。以前,如果您提出新协议(例如,象 jdbc:database),那么若没有协议处理程序,则您不能将 jdbc:database 字符串作为 url 处理。相反,您不得不严格地将它作为字符串处理,这正是 jdbc 现在所做的。
  
    uri 的典型格式是:[scheme:][//authority][path][?query][#fragment],其中 authority 通常就是主机名。但是,它还可以包括用户登录信息和端口:[userinfo@]host[:port]。uri 类自身提供了一系列的 getter 方法,以便了解 uri 各个特定的部分。在您先前传递看上去象 url 的字符串(但这仅为了描述 url 而非使用它)的地方,您应当使用该类。
  
  用 networkinterface 列出网络连接
  
    您是否曾经想知道哪个联网接口是可用的,但是在不回复到本机代码的情况下又不知道该如何询问呢?通常,连接至因特网的大多数机器中有两个连接:到其自身的本地循环和到其本地服务供应商的连接。但是,有些机器是多宿主的。它们有多个网卡,每个网卡都有一个到因特网的独立连接并且都有自己的名称和地址。有了这个新的 networkinterface 接口,您就可以在向外发送多点广播数据报时指定使用哪个网卡,或查看网络连接是否正常。清单 1 演示了该类的用法:
  
  
  
  清单 1. 列出网络接口 import java.net.*;
  
  import java.util.enumeration;
  
  public class nets {
  
  public static void main(string args[]) throws socketexception {
  
  enumeration enum = networkinterface.getnetworkinterfaces();
  
  while (enum.hasmoreelements()) {
  
  networkinterface net = (networkinterface)enum.nextelement();
  
  system.out.println(
  
  "names: " + net.getname() + " / " + net.getdisplayname());
  
  enumeration enum2 = net.getinetaddresses();
  
  while (enum2.hasmoreelements()) {
  
  inetaddress address = (inetaddress)enum2.nextelement();
  
  system.out.println("/taddress: " + address.gethostaddress());
  
  }
  
  }
  
  }
  
  }
  
  
  
    您运行该程序所得的结果肯定是不同的。清单 2 包括了您想看到的输出样本:
  
  
  
    清单 2. 清单 1 的样本结果 names: lo / ms tcp loopback interface
  
  address: 127.0.0.1
  
  names: eth0 / 3com etherlink pci
  
  address: 192.168.0.109
  
  
  
  对未连接套接字和非绑定套接字的支持
  
    通常,象在套接字之间进行读写之类的操作都是阻塞操作。在操作完成之前,调用线程都不能继续运行。在 merlin 新 i/o(nio)类的帮助下,联网类现在可以是非阻塞型的。无论哪一种情况(阻塞或非阻塞),新的 inetsocketaddress 和 socketaddress 类都允许您打开到主机和端口的连接,然后在真正连接到主机之前为该连接设置一些选项。清单 3 显示了基本的操作序列:
  
  
  
  清单 3. 连接至主机和端口 string hostname = ...;
  
  int port = ...;
  
  socketaddress socketaddress =
  
  new inetsocketaddress(host, port);
  
  socketchannel channel = socketchannel.open();
  
  channel.configureblocking(false);
  
  channel.connect(socketaddress);
  
  
  
    请在下个月的专栏文章中查阅有关 nio 包的更多信息。
  
  用安全套接字进行连接
  
    merlin 中有一个新的包:javax.net.ssl。该包提供了使用 java 安全套接字扩展(java secure socket extension,jsse)的安全通信,该扩展更常用的名称是 https url 的安全套接字层(secure sockets layer,ssl)支持。您不再需要用标准扩展库来实现 ssl 支持 - 它现已随核心库一起提供。通过请求来自 sslsocketfactory 的 ssl 套接字,您自动地就获得了一个安全连接(假设您所连接的服务器支持该功能)。获取套接字后,您不必再执行任何特殊的操作了 - 它会完全象普通套接字那样进行通信。
  
    在清单 4 中,我们使用 ssl 来连接用户指定的站点,或 verisign,并获取该站点的入口页面。可以随意将输出保存到文件中,以便查看。
  
  
  
  清单 4. 通过安全套接字进行连接 import java.io.*;
  
  import java.net.*;
  
  import javax.net.*;
  
  import javax.net.ssl.*;
  
  public class sslsample {
  
  static final int https_port = 443;
  
  public static void main(string args[]) throws ioexception {
  
  string hostname;
  
  // if host not provided, connect to verisign
  
  if (args.length == 0) {
  
  hostname = "www.verisign.com";
  
  } else {
  
  hostname = args[0];
  
  }
  
  // get socket factory
  
  socketfactory factory = sslsocketfactory.getdefault();
  
  // get socket from factory
  
  socket socket = factory.createsocket(hostname, https_port);
  
  // send request
  
  outputstream os = socket.getoutputstream();
  
  printwriter pw = new printwriter(os);
  
  // setup command
  
  string command = "get / http/1.0/r/n/r/n";
  
  pw.print(command);
  
  pw.flush();
  
  // get response
  
  inputstream is = socket.getinputstream();
  
  inputstreamreader isr = new inputstreamreader(is);
  
  bufferedreader br = new bufferedreader(isr);
  
  string line;
  
  while ((line = br.readline()) != null) {
  
  system.out.println(line);
  
  }
  
  pw.close();
  
  br.close();
  
  socket.close();
  
  }
  
  }
  
  
  
    还有一个 httpsurlconnection 类,可以象 jave.net.urlconnection 那样使用它。
  
  旧的类,新的技巧
  
    并不是所有的联网增强技术都是在新的类(和包)中实现的。许多现有的类也得到了增强。有些功能主要是在后台进行的,比如改进的 ftp 协议处理程序。现在,merlin 的功能和 rfc1738 和 rfc959 的功能(请参阅参考资料)匹配得更加紧密了,包括对被动方式的支持。另外,urlencoder 和 urldecoder 类

扫描关注微信公众号