1、第05讲 Java网络编程,5.1 Java语言,Java是Sun公司于1995年正式推出的一种全新的纯面向对象的程序设计语言,它具有高性能,跨平台性,可移植性,动态性,稳定性和安全性,多线程等优良特性。将Java程序嵌入HTML中,生成可以交互的智能的主页,而最主要的是它具有构造动态画面的功能,为用户提供了良好的程序设计环境,特别适合于Internet/Intranet编程,还能和WWW很好的协同工作。因此,人们称Java为“网络上的世界语”。Java降低了Internet应用程序的编写难度。在WWW世界中有数不清的Java小应用程序,它们能够产生一些有趣的效果,使Internet世界变得更
2、加丰富多彩。,针对网络分布式计算环境,Java通过其网络类库提供了对网络程序设计 的良好支持。Java提供的网络类库和子类库主要包括:,1 java的基本网络类库 2 .ftp 处理ftp协议 3 .www.content 处理Web页面内容 4 .www.html 提供html语言支持 5 .www.http 提供http协议支持 6 .ssl Networking with Secure Socket Layer) 7 java.rmi Remote Method Invocation) 8 javax.rmi Remote Method Invocation for IIOP(互联网互
3、操作ORB协议) ,5.2 Java网络程序设计基础,Java语言在编写网络程序时,大量使用了Java的输入输出流类。流是指在计算机的输入与输出之间传输数据的序列,输入流代表从外设 流入计算机的数据序列,而输出流代表从计算机流向外设的数据序列。Java中有两个流的基本类:基本输入类InputStream和基本输出类 OutputStream。,5.2 Java网络程序设计基础,OutputStream。 public abstract class OutputStream public abstract void write(int b) throws IOException public v
4、oid write(byte data) throws IOException public void write(byte data, int offset, int length) throws IOException public void flush( ) throws IOException public void close( ) throws IOExceptionpublic abstract class InputStream public abstract int read( ) throws IOException public int read(byte input)
5、throws IOException public int read(byte input, int offset, int length) throws IOException public long skip(long n) throws IOException public int available( ) throws IOException public void close( ) throws IOException,5.2 Java网络程序设计基础,JAVA在网络程序中的应用范畴 1、两层的客户服务器体系结构 客户端:JAVA应用程序 服务器端:与数据源的沟端通过 Socket/
6、RMI (Java远程方法调用) JDBC( Java数据库连接),5.2 Java网络程序设计基础,JAVA在网络程序中的应用范畴 2、基于HTML的三层体系结构 客户端:浏览器 HTML 服务器端:与数据源的沟端通过 JSP (Java Server Pages) Java servlet /ASP, ASP.NET/ PHP, Perl等 数据库:MSSqlServer、Oracle,5.2 Java网络程序设计基础,JAVA在网络程序中的应用范畴 3、基于HTML的四层体系结构 客户端:浏览器HTML WEB容器:JSP,Java Servlet (表示逻辑层) 应用服务器:Socke
7、t/RMI、JDBC、EJB/CORBA (应用逻辑层) 负责数据库访问、ERP、邮件服务器等 数据库: MSSqlServer、Oracle,5.2 Java网络程序设计基础,JAVA在网络程序中的应用范畴 4、基于Applet的四层体系结构 客户端:浏览器JavaApplet WEB容器:JSP,Java Servlet (表示逻辑层) 应用服务器:Socket/RMI、JDBC、EJB/CORBA (应用逻辑层) 负责数据库、ERP、邮件服务器等 数据库: MSSqlServer、Oracle,5.2 Java网络程序设计基础,5.3 Internet寻址,处理主机名称及IP地址: 类:
8、 .InetAddress 方法: public byte getAddress()public static InetAddress getAllByName(String host) throws unkownHostExceptionpublic static InetAddress getByName(String host) throws UnkownHostExceptionpublic String getHostAddress()public String getHostName() 异常:.UnknownHostException,5.3 Internet寻址,为区分Inte
9、rnet中的计算机,Java在中提供了类InetAddress,用于描述计算机的IP地址和域名。InetAddress类没有构造方法,而是依靠静态的类方法getByName()等,根据参数host指定的计算机来生成InetAddress的对象实例。,下面的例子演示java如何根据域名自动到DNS上查找IP地址 import .*; public class getIP public static void main(String args) InetAddress whu=null;try whu=InetAddress.getByName(“”);catch(UnknowHostExcept
10、ion e) System.out.println(whu); ,例:获取本机的IP地址 import .*; public class getLocalHostTest public static void main() InetAddress myIP=null;byte Bytes;int fourBytes = new int4;try myIP=InetAddress.getLocalHost();catchUnknowHostException e)Bytes = myIP.getAddress();for (int i = 0, i 4, i + ) fourBytesi = B
11、ytesi /创建inetAddress类不用构造函数(不用new) /getLocalHost()是InetAddress类的一个静态方法,返回运行该函数的计 算机的主机信息。,5.3 Internet寻址(1),Java提供的网络功能有三大类: URL, Socket, Datagram。 URL是三大功能中最高级的一种,通过URL Java程序可以直接送出或读入网络上的数据。 Socket是传统网络程序最常用的方式,可以想象为两个不同的程序通过网络的通信信道。 Datagram是更低级的网络传输方式,它把数据的目的地址记录在数据包中,然后直接放在网络上。,5. 4 Java主要网络功能类
12、,5. 4.1 Java与URL,URL对象由协议名、主机名、端口号、路径名(虚拟目录和资源名)、用户名称与密码、CGI参数等部分构成。JAVA的URL对象提供了四种构造函数:URL url1 = new URL(“http:/:80/”);URL url2 = new URL(“http”,””,”index.html”);URL url3 = new URL(“http”,””,80,”index.html”;URL url4 = new URL(url1,”research/cs.html”);在创建了URL对象后,可以通过openStream()方法打开与资源的连 接并返回一个用于从资
13、源读取字节数据的InputStream对象。,5. 4.1 Java与URL,在中,与URL有关的类有: 接口: URLStreamHandleFactory 类: .HttpURLC.JarURLC.URL.URLClassL.URLC.URLD.URLE.URLStreamHandler 异常: .MalformtedURLE.UnkownServiceException,/通过URL读取WWW服务器上的数据 /将URL位置的数据转成一个数据流 URL url=new url(“http:/ DataInputStream data=newDataInputStream(url.openS
14、tream(); /从数据流中读出数据 String line=data.readLine(); while(line!=null) system.out.println(line);line=data.readLine(); ,5. 4.1 Java与URL(1),例子:,public boolean action(Event evt, Object arg) try String line;String str=textfield.getText();url=new URL(str);data=new DataInputStream(url.openStream();while(line=
15、data.readLine()!=null)textarea.appendText(line); data.close();catch(MalformedURLException me)System.out.println(“Error URL“);catch(IOException ie)System.out.println(“Error IO“);return true; ,5. 4.1 Java与URL(2),URL双向通信(URLConection) URLConnection是一个以http为中心的类,用于在URL基础之上实现与URL的双向通信。1. 建立连接URL url=new
16、URL(“http:/ con=url.openConnection();2. 向服务器端送数据PrintStream outStream=new PrintStream(con.getOutputStream();outStream.println(“http 1.0 ”);3. 从服务器读数据DataInputStream inStream=new DataInputStream(con.getInputStream();inStream.readLine();,5. 4.1 Java与URL(3),从URL中得到的输出流通常与一个CGI程序结合一起工作,客户端,DataOutputStr
17、eam,DataInputStream,CGI程序,STDIN,STDOUT,服务器,connectiuon,getchar(),putchar(),java程序,URLConnection同时支持get和post两种机制一般的格式. 缺省情况下为post method。 URL和URLConnection的区别在于前者代表一个资源的位置,后者代表一种连接。 下面的例子中Java程序访问cgi程序,并传给它10个数据,cgi程序接收后,排序,并传送回来。 连接的建立、数据流的建立、java如何发数据、如何接收数据、cgi程序如何发送和接收.,5. 4.1 Java与URL(4),import
18、java.io.*; import .*; public class test_cgi public static void main(String args) throws Exception URL url = new URL(“http:/ URLConnection connection = url.openConnection(); connection.setDoOutput(true);PrintStream out = new PrintStream(connection.getOutputStream(); out.println(“0123456789“);out.clos
19、e(); DataInputStream in = new DataInputStream(connection.getInputStream();String inputLine;while (inputLine = in.readLine() != null) System.out.println(inputLine);System.in .read ();in.close(); ,5. 4.1 Java与URL(5),#include “stdio.h“ main() int array10; int i,j,k;printf(“Content-type:text/plainnn“);f
20、or(i=0;i=9;i+)arrayi=getchar(); /read data from InputStreamfor(i=0;i=8;i+) for(j=i;j=9;j+) if(arrayiarrayj) k=arrayj; arrayj=arrayi; arrayi=k; printf(“nOutput number!n“);for(i=0;i=9;i+) printf(“%c“,arrayi); /write data to OutputStream ,CGI基础知识,5. 4.1 Java与URL(6),5.4.2 Socket,Socket是网络上运行的程序之间双向通信链路的
21、最后终结点,IP与端口的组合得出一个套接字,可以基本分辨internet上运行的程序,端口号:TCP/IP协议为每种服务定义了一个端口,当一台计算机上运行不同服务器程序时,根据端口号不同提供相应的服务。 端口号不是计算机上的物理连接器,它只是具有软件意义的假想端口。 常用Internet服务的端口号:ftp 21 www 80telnet 23 nntp 119Dns 53 Pop3 110Smtp 25 Rpc 135,5.4.2 Socket (1),处理TCP通信协议 接口: SocketImplFactory SocketOptions 类: .ServerS.S.SocketImpl
22、异常: .BindE.ConnectE.NoRouteToHostE.ProtocolE.SocketException,5.4.2 Socket (1),例:显示服务器与客户机间的通信(服务器端),PrintStream ps=null; DataInputStream dis=null; String username; ServerSocket serverSocket=null; Socket clientSocket=null;,try serverSocket=new ServerSocket(1111); catch (IOException e) System.out.prin
23、tln( “Error”+e); System.exit(1);,try clientSocket=serverSocket.accept(); catch (IOException e)System.out.println(“Accept failed.“);System.exit(1);,创建服务器(端口号),定义数据成员,服务器等待 网络连接,5.4.2 Socket (2),ps=new PrintStream(clientSocket.getOutputStream(); dis=new DataInputStream(clientSocket.getInputStream();,建
24、立socket流,向客户发出登录要求,ps.println(“login:“); ps.flush();,5.4.2 Socket (3),ps.println(“login sucessful“); ps.flush(); System.out.println(username+“ has logged off“); ,读客户端信息,通知客户连接完毕,if (username=dis.readLine()=null) System.out.println(“readLine returned null“);System.exit(1); System.out.println(“Usernam
25、e:“+username);,5.4.2 Socket (4),例:显示服务器与客户机间的通信(客户端),创建Socket实例,PrintStream output; DataInputStream input; String string; Socket socket=null;,定义数据成员,trysocket=new Socket(“127.0.0.1“,1111); catch(IOException e)System.out.println(“Error ”+e); return;,input=new DataInputStream(socket.getInputStream();
26、output=new PrintStream(socket.getOutputStream();,建立socket流,5.4.2 Socket(c),.,System.out.println(input.readLine();,读socket流 (看到提示),System.in.read(bArray); String s=new String(bArray,0); output.println(s);,从键盘上读送用户 名送给服务器端,关闭流,socket.close(); input.close(); output.close(); System.out.println(“Done“);,
27、System.out.println(input.readLine(); System.out.print(“Logging off.“);,读服务器反馈,5.4.2 Socket(c),例:SMTP 客户端程序HELLO ,5.4.2 Socket(c),例:SMTP 客户端程序,5.4.2 Socket(c),程序内容,例:POP3 客户端程序HELLO ,5.4.2 Socket(c),例:POP3客户端程序,5.4.2 Socket(c),程序内容,5.4.3 Datagram,TCP/IP传输层由两个并列的协:TCP,UDP. 一般套接字(TCP)提供一个可靠的传输模型作为两个网络端
28、点的字节流,有纠错能力. UDP没有保持的连接和数据流,数据报是一个网络上发送的独立信息,它的到达,到达时间,以及内容不能得到保证.,socket,server,client,datagram,server,client,TCP提供高可靠性服务,适用于一次要传输交换大量报文的情况,信道上传递的包不需要源地址和目的地址 UDP提供高效率服务,适用于依次传输交换少量报文的情形 (如数据库查询),每个数据包要包含目的地址和端口号. 数据报文的使用以包为中心:打包,拆包. J包支持两种不同的在网络上送数据的方法:一般套接字和数据报文套接字.,5.4.3 Datagram(1),5.4.3 Datagr
29、am,处理UDP通信协议 接口: DatagramSocketImplFactory 类: .DatagramP.DatagramS.DatagramSocketI.MulticastSocket异常: .SocketException,发出报文的标准步骤如下: 1. 定义数据成员DatagramSocket socket;DatagramPacket packet;InetAddress address;(用来存放接收方的地址)int port; ;(用来存放接收方的端口号) 2. 创建数据报文Socket对象try socket=new DatagramSocket(1111);catch
30、(.SocketException e) socket 绑定到一个本地的可用端口,等待接收客户的请求.,5.4.3 Datagram (2),3.分配并填写数据缓冲区(一个字节类型的数组)byte Buf=new byte256; 存放从客户端接收的请求信息. 4.创建一个DatagramPacketpacket=new DatagramPacket(buf, 256);用来从socket接收数据,它只有两个参数5. 服务器阻塞socket.receive(packet);在客户的请求报道来之前一直等待,5.4.3 Datagram (3),6. 从到来的包中得到地址和端口号InetAddre
31、ss address=packet.getAddress();int port=packet.getPort(); 7. 将数据送入缓冲区或来自文件,或键盘输入 8. 建立报文包,用来从socket上发送信息packet=new DatagramPacket (buf,buf.length, address,port); 9. 发送数据包 10.关闭socketsocket.send(packet); socket.close();,5.4.3 Datagram (4),客户端接收包的步骤如下: 1. 定义数据成员int port; InetAddress address;DatagramSo
32、cket socket;DatagramPacket packet;byte sendBuf=new byte256; 2. 建立socketsocket=new DatagramSocket();,5.4.3 Datagram (5),3. 向服务器发出请求报文address=InetAddress.getByName(args0);port=parseInt(args1);packet=new DatagramPacket(sendBuf,256,address,port);socket.send(packet);这个包本身带有客户端的信息 4. 客户机等待应答packet=new Dat
33、agramPacket(sendBuf,256);socket.receive(packet);(如果没有到就一直等待,因此实用程序要设置时间限度),5.4.3 Datagram (6),5. 处理接收到的数据String received=new String(packet.getData(),0); System.out.println(received);数据报套接字首先是强调发送方和接收方的区别,同时也指出服务器和客户之间的不同: 一个客户机必须事先知道服务器的地址和端口,以便进行出事连接 一个服务器从它接收到的数据报文中读取客户端的地址和端口.,5.4.3 Datagram (7),
34、.,建立数据报socket();,建立一个报文包packet,等待请求报文,建立数据报socket,建立一个请求包,发出请求,获得对方地址,构成信息包,发送出去,创建接收包,等待接收,5.4.3 Datagram (8),5.5 JAVA的网络安全通信编程,基于因特网安全的重要性,JAVA提供了对一些网络安全协议和API的支持:JAVA安全性原则JAVA身份验证和授权服务(Java Authentication and Authorization Service,JAAS) ,JAAS 提供了一种灵活的、说明性的机制,用于对用户进行认证并验证他们访问安全资源的能力。JAVA加密扩展(Java
35、Cryptography Extension,JCE)JAVA安全套接字扩展(Java Secure Socket Extension,JSSE)。 JSSE 定义了通过安全套接字层(SSL)进行安全 Web 通信的一种全 Java 的机制。 通过结合JAAS和JSSE,可以使应用程序: 验证用户就是他或者她所宣称的那个人(认证)。 保证允许他或者她访问所要求的资源(授权)。 通过安全网络连接进行完整的信息交换(传输)。,5.5 JAVA安全,处理网络及权限 类: .Authenticator .NETPermission .PasswordAuthentication .SocketPerm
36、ission .SocketException 内容处理器 接口: ContentHandlerFactory 类: .ContentHandler .SocketException,5.5 JAVA安全,基于因特网安全的重要性,JAVA提供了对一些网络安全协议和API的支持:JAVA安全性原则JAVA身份验证和授权服务(Java Authentication and Authorization Service,JAAS)JAVA加密扩展(Java Cryptography Extension,JCE)JAVA安全套接字扩展(Java Secure Socket Extension,JSSE)
37、,5.5 JAVA内容处理,内容处理器 接口: ContentHandlerFactory 类: .ContentHandler .SocketException,5.6 Java远程调用方法(RMI),使用Socket编程需要大量重复编码,在 复杂分布式操作时显得非常麻烦,而且易于出错。因此,如何快速、高效、安全、可扩展地进行网络分布式计算,是开发者们一贯追求和倡导的主题。 Java远程方法调用(Remote Method Invocation,RMI)允许使用Java编写分布式对象。远程方法调用(Remote Method Invocation, RMI),可以在不同的Java虚拟机(JV
38、M)之间实现对象与对象的通信。,5.6 Java远程调用方法(RMI),RMI的主要优点如下: 面向对象可以将对象作为调用远程方法的参数和返回值,将Java编程模型扩展到机器边界(和Java虚拟机(JVM)边界之外),不需要任何特殊语法。 可移动属性RMI可以将属性(类的实现程序)在客户端和服务器之间移植。 安全性使用内置的安全机制保证分布式程序的执行安全。 分布式垃圾收集分布式垃圾回收机制可以保证系统自动回收服务器上不被客户机引用的服务器对象。 并行计算RMI采用多线程的处理方法,使得服务器较为方便地并行处理多个客户端请求。 分布式计算将复杂任务分布在不同的系统上运行是RMI的最显著特性。,
39、. 体系结构 RMI由三层构成,分别为:存根框架,远程引用层,传输层。 三层之间的关系如图所示:,RMI实际上是Java上的远程调用机制。实现的基本原理在于通过客户端代理与服务器代理之间的交换,使得客户端软件可以像调用本地对象一样访问服务器上的对象。存根(STUB)和框架就分别是客户端和服务器端的代理。,5.6 Java远程方法调用(RMI)(1),RMI为我们引入了两种特殊类型的对象,称为存根(Stub)和框架(Skeleton),它们组成了RMI的第一层。 存根RMI中代表远程对象的客户机代理,用于定义远程对象的所有接口。 存根将保持与服务器对象的连接,客户机程序可以直接引用存根。 框架框
40、架Skeleton实际上是服务器代理,用于根据RRL的要求调用服务器上的对象,并且将调用结果返回给RRL。在远程通信的时候,要利用TCP/IP协议,做很多底层数据的打包传输。运用Java技术,我们先要把数据或者对象转换成字节流(byte stream),便于网络传输,这个过程叫汇集(marshaling);当收到远程传来的字节流后,我们要把流信息转换成对象或者数据,这个过程叫解读(unmarshaling),它与汇集刚好相反。存根、框架与远程引用层之间是一种调用和被调用关系,这种是通过调动流来实现的;存根将参数通过调动流传递给RRL,也通过调动流获取来自RRL的调用结果;服务器的RRL通过调动
41、流访问服务器对象,同样也获取来自对象的返回值。服务器与客户机RRL之间是通过独立的引用协议来传递需要访问的对象、调用的方法、传递的参数、方法返回值的。,5.6 Java远程调用方法(RMI)(2),远程引用层远程引用层(Remote Reference Layer,RRL)在服务器与客户机之间实现独立的引用协议,这样RRL的改变不会影响其他的层次。 远程引用层定义和支持着RMI连接的调用语义(semantics)。 RMI进行远程访问要用到JRMP(Java Remote Method Protocol,即Java远程方法协议), 这一层提供专用于JRMP的RemoteRef对象,它位于jav
42、a.rmi.server包内,代表着远程对象的一个句柄。RemoteRef使用远程引用来执行远程对象的一个远程方法调用。,5.6 Java远程调用方法(RMI)(2),传输层传输层(Transport Layer)在JVM之间建立基于流的网络连接,并且负责设置和管理这些连接。这时候,RMI使用一种线级(wire-level)协议进行基于TCP/IP的连接,该协议就是Java远程方法协议(JRMP,即Java Remote Method Protocol)。在JDK版本1.2开始,JRMP不再需要Skeleton,而是使用reflection来建立与远程服务的连接。为了生成Stub,我们须用rm
43、ic。当前的RMI实现中,传输层建立在TCP/IP基础上,设计用于在客户和服务器之间建立一条连接(即使联网有障碍)。,5.6 Java远程调用方法(RMI)(3),传输层负责建立和维护客户机和服务器之间的连接,共由4个抽象部分构成。 端点(endpoint)用于引用包含java虚拟机的地址空间,是具体传输接口的引用。 通道(channel)两个地址空间之间的通路。负责客户机和服 务器之间的各种连接。 连接(connection)是客户机和服务器之间数据(变元和返回值)传输的抽象表示。 传输(transport)负责建立本地地址空间和远程端点之间的通道。,5.6 Java远程调用方法(RMI)(
44、3),用RMI编写一个分布式应用,核心有以下三方面: ()定位远程对象 一个应用可以利用RMI的名字服务功能注册器远程对象。 可以象操作普通对象一样传送并返回一个远程对象的引用(指针)。 ()与远程对象通信: 底层的通信由RMI实现,对于系统开发人员来说,远程调用和标准的Java方法调用没有什么区别。 ()为需要传递的对象装载类的字节码 RMI允许调用者向远程对象传递对象,因此 RMI提供这种装载对象的机制。,. 编程示例,5.6 Java远程调用方法(RMI)(4),下面我们来看实现一个远程对象的具体步骤:(1)定义一个扩展了Remote接口的接口import java.rmi.*;publ
45、ic interface RemoteInterface extends Remote public String getMessage(String msg) throws RemoteException;,5.6 Java远程调用方法(RMI)(5),( 2)定义一个实现上面接口的类import java.rmi.*; import java.rmi.server.*; public class RemoteServer extends UnicastRemoteObject implentments RemoteInterface String name;public RemoteSer
46、ver(String name) throws RemoteException super();this.name = name;public String getMessage(String msg) throws RemoteException String str = “The Server is:” + name + “, your message is:” + msg;System.out.println(str);return str;,5.6 Java远程调用方法(RMI)(6),public static void main(String args) System.setSecurityManager(new RMISecurityManager();try String myName = “ServerTest”;RemoteObject theServer = new RemoteObject(myName);Naming.rebind(myName, theServer);System.out.println(“Ready to continue:”);catch(Exception e) System.out.println(“Server Exception:” + e.toString(); ,