500 likes | 705 Views
第 13 章 网络技术和应用开发. 教学目标. 13.1 Java 网络技术概述 13.2 URL 与网络应用 13.2.1 URL 类 13.2.2 用 applet 访问 URL 资源 13.2.3 Web 浏览器的设计 13.2.4 URLConnection 类 13.3 基于流套接字的客户 / 服务器通信 13.3.1 InetAddress 类 13.3.2 Socket 类 13.3.3 ServerSocket 类 13.3.4 基于流套接字的客户 / 服务器的通信过程 13.3.5 多线程实现多用户网上聊天. 教学目标 ( 续 ).
E N D
教学目标 • 13.1 Java网络技术概述 • 13.2 URL与网络应用 • 13.2.1 URL类 • 13.2.2 用applet访问URL资源 • 13.2.3 Web浏览器的设计 • 13.2.4 URLConnection类 • 13.3 基于流套接字的客户/服务器通信 • 13.3.1 InetAddress类 • 13.3.2 Socket类 • 13.3.3 ServerSocket类 • 13.3.4 基于流套接字的客户/服务器的通信过程 • 13.3.5多线程实现多用户网上聊天
教学目标(续) • 13.4 基于数据报套接字方式的客户/服务器通信 • 13.4.1 DatagramPacket类 • 13.4.2 DatagramSocket类 • 13.4.3基于数据报套接字的客户/服务器的通信应用实例
13.1 Java网络技术概述 • Java提供两种网络支持机制: • URL的类 • 用于访问Internet网上资源的应用 • Socket通信的类 • 基于TCP/IP协议中传输层接口Socket • 针对Client/Server模型的网络应用 • 以及实现某些特殊协议的网络应用。 • 网络通信包java.net:包含有网络通信所需要的类和接口
13.1 Java网络技术概述 • 基于流套接字(stream sockets )的网络通信 • 应用程序将网络通讯看做是数据流; • 面向连接的网络服务 • 用于传送的协议是TCP(Transmission Control Protocol)协议。 • 基于数据报套接字(datagram sockets)的网络通信 • 程序将要传递的数据打包分成一个个小的数据包。 • 服务主机跟客户机是无连接的 • 传送的协议是UDP(User Datagram Protocol)协议。
13.2 URL与网络应用 • URL(Uniform Resource Locator): • 用于表示Internet上的网络资源; • 利用URL对象中提供的方法,可直接读写网络中的数据。 • 一个URL组成:协议名、主机名、端口号、路径文件(文件路径及文件名)。 例如, http://www.tsinghua.edu.cn:80/home/homepage.htm 表示: 协议:http, 主机地址:www.tsinghua.edu.cn 端口号:80, 路径文件:/home/homepage.htm。
13.2.1 URL类 • Java将URL封装成URL类. • 创建URL对象的构造方法: (1)URL(String spec) 用指定的一个String来创建一个URL对象; (2)URL(String protocol,String host,int port,String file): 用指定的协议、主机名、端口号、路径文件来创建一个URL对象 (3)URL(String protocol, String host, String file) 用指定的协议、主机名、路径及文件名来创建URL对象; (4)URL( URL context, String spec) 用已存在的URL对象来创建URL对象。
13.2.1 URL类 • 获取URL对象属性的常用方法: • String getProtocol():获取URL传输的协议; • String getHost():获取URL的机器名称; • int getPort():获取URL的端口号; • String getFile():获取URL的文件名,包括路径和文件名; • Obect getContent():获取URL的内容; • InputStram openStream():打开与URL的连接,返回一个输入流,通过这个输入流读取数据; • URLConnection openConnection():返回与URL进行连接的URLConnection对象;
13.2.1 URL类 • 例13-1 URL对象的创建及使用。
import java.net. *; public class Myurl{ public static void main(String args[]) {try { URL url=new URL ("http://www.tsinghua.edu.cn:80/home/homepage.htm"); System.out.println("the Protocol: “ +url.getProtocol()); System.out.println("the hostname: "+url.getHost()); System.out.println("the port: "+url.getPort()); System.out.println("the file: "+url.getFile()); System. out. println(url.toString()); } catch(MalformedURLException e) { System.out.println(e); } } }
13.2.2 用Applet访问URL资源 • 例13-2利用Applet显示网络上其他HTML文档。 在IE浏览器执行showdoc.htm文件执行后,将在新的IE窗口中显示163网站的内容。 • 利用applet的AppletContect接口中的方法showDocument(),将使执行Applet的浏览器显示指定的URL资源。 showDocument(URL url,String target) target:指定显示URL内容的窗体. Target值为 “_bank”表示在新开的窗体URL资源。
//showdoc.java import javax.swing.*; import java.awt.*; import java.net.*; public class showdoc extends JApplet { URL docur= null; public void paint(Graphics g) { try { docur=new URL("http://www.163.com"); } catch (MalformedURLException e) { System.out.println("Can ope the URL "); } if (docur != null) getAppletContext().showDocument(docur,"_blank"); } }
// showdoc.htm <html> <applet code = "showdoc.class" width = "600" height = "500"> </applet> </html>
13.2.3 Web浏览器的设计 • 用application实现一个简单的Web浏览器。 • 使用swing GUI组件JEditorPane,显示Web服务器上的文件内容。 • JEditorPane组件能显示无格式或带格式的HTML文本。 • JEditorPane的方法setPage(URL url),将下载由url定位的文档并显示在JEditorPane组件中。 • 用户在窗体顶部的JTextField中输入URL后,将URL的HTML格式的文本,在JEditorPane中显示。
13.2.3 Web浏览器的设计 • 如果JEditorPane含有的HTML文档中含有超链接,当用户单击其中一个超链接时,则JEditorPane产生事件HyperlinkEvent(javax.swing.event包中),并通知所有已注册的HyperlinkListener对象。 • HyperlinkListener接口的方法hyperlinkUpdate() • 处理超链接事件HyperlinkEvent: • 在JEditorPane中显示超链接的Web网页。
13.2.3 Web浏览器的设计 wcontentsArea.addHyperlinkListener( new HyperlinkListener() { // if user clicked hyperlink, go to specified page public void hyperlinkUpdate( HyperlinkEvent event ) { if ( event.getEventType() == HyperlinkEvent.EventType.ACTIVATED ) getThePage( event.getURL().toString() ); } } ); • HyperlinkEvent类中包含一个嵌套内部类EventType,此内部类声明的三个静态常量: • ACTIVED(表示用户单击一个超链接以改变Web网页) • ENTERED(表示用户把鼠标移到一个超链接上) • EXITED(表示用户把鼠标移离一个超链接)。
13.2.3 Web浏览器的设计 • 例13-3用Java的应用程序实现一个简单的Web浏览器。 假定用户在窗体顶部的JTextField中输入google的Web地址后,将在JEditorPane中显示google的Web页面。用户单击其中一个超链接“高级搜索”,将显示超链接“高级搜索”的Web网页
13.2.4 URLConnection类 • URLConnection是一个抽象类,它提供了与URL资源的双向通信(读写操作)。 • URLConnection对象的构造: 通过调用URL对象的方法: URLConnection openConnection() 来得到一个URLounechon对象,但这并未建立与指定的URL的连接,还必须调用URLConnection对象的connect()方法建立连接。
13.2.4 URLConnection类 • URLConnection对象的常用方法: void connect():打开到此 URL 引用的资源的通信链接。 int getContentLength():获得文件的长度; String getContentType():获得文件的类型; long getDate():获得文件创建的时间; long getLastModified() //获得文件最后修改的时间; InputStream getInputStream():获得输入流,以便读取文件的数据; OutputStream getOutputStream():获得输出流,以便写文件。
13.2.4 URLConnection类 • 例13-4 从Web服务器上将URL文件下载到本机,并将文件的信息显示到屏幕。 该程序运行后,将文件http://www.tsinghua.edu.cn:80/home/homepage.htm 下载到本机的当前文件夹下,并在屏幕上输出文件homepage.htm内容。
13.3 基于流套接字的客户/服务器通信 • 基于流套接字的数据传递方式: • 在两个网络应用程序(服务器应用和客户机应用)之间发送和接收信息时,需要建立一个可靠的连接。 • Java中与流套接字相关的类: • InetAddress对象描绘了32位或128位IP地址 • ServerSocket对象用在服务器应用中 • Socket对象是建立网络连接时使用的
13.3.1 InetAddress类 • Internet上通过IP地址或域名标识主机,而类InetAddress用来表示与Internet地址的相关的操作。 • InetAddress类没有构造方法,要创建该类的实例对象,通过该类的静态方法获得该对象。
13.3.1 InetAddress类 • InetAddress类的常用一组静态方法: InetAddress getLocalHost():获得本地机的 InetAddress对象。 InetAddress getByName(Stung host):获得由host指定的InetAddress对象,host是计算机的域名。 InetAddress[]getAllmyName(String host):在Web中,可以用相同的名字代表一组计算机获得具有相同名字的一组InetAddress对象。
13.3.1 InetAddress类 • InetAddrss对象的常用一组方法: byte[] getAddress():得到IP地址; String getHostName():得到主机名字; String toString():得到主机名和IP地址的字符串。
13.3.1 InetAddress类 • 例13-5 InetAddress类的应用. 程序运行的机器已经与Internet网连接好,程序运行后的输出结果:
import java.net.*; class InternetAddress { public static void main(String args[]) { try { InetAddress iads; iads= InetAddress.getByName("www.163.com" ); System.out.println("hostname="+ iads.getHostName()); System.out.println(iads.toString() ); } catch(Exception e) { System.out.println(e); } } }
13.3.2 Socket类 • Socket是建立网络连接时使用的 • 在连接成功时,客户和服务器应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。 • 当客户程序需要与服务器程序通讯的时候,客户程序在客户机要创建一个Socket对象。 • Socket类的常用构造方法: (1)Socket(InetAddress addr, int port) (2)Socket(String host, int port) 两个构造方法都创建了一个用于连接服务器主机和指定端口的客户端流套接字。
13.3.2 Socket类 • 在创建了一个Socket对象,应用程序 • 通过调用Socket对象的getInputStream()方法:获得输入流,以读取对方传送来的信息; • 通过调用Socket对象的getOutputStream()方法获得输出流,向对方发送消息。 • 在读写活动完成之后,调用close()方法关闭流和流套接字。 • 例如: 创建了一个服务器应用的主机地址为198.163.227.6,端口号为50000的客户端Socket对象,然后从这个新创建的Socket对象中读取输入流和输出流,最后再关闭Socket对象和流。
13.3.2 Socket类 Socket s = new Socket ("198.163.227.6",50000); InputStream inputstream = s.getInputStream (); OutputStream outputstream = s.getOnputStream (); …. // Read or write from the inputstream/outputstream inputstream.close (); outputstream.close (); connection.close ();
13.3.3 ServerSocket类 • 服务器程序需要创建一个ServerSocket对象,用于在指定端口上监听客户端连接请求。 • ServerSocket类的构造方法: (1)ServerSocket(int port) 在指定端口上创建一个ServerSocket对象。服务器应用使用ServerSocket监听指定的端口,端口建议使用大于1024。 (2)ServerSocket(int port,int queueLength) Server在指定端口上监听客户端连接请求,并指定允许连接的客户最大数目。
13.3.3 ServerSocket类 • 创建一个ServerSocket对象后,接下来服务程序进入无限循环之中.
服务器端应用 客户端应用 (1)创建ServerSocket对象 注册服务器端口和允许连接的用户最大数 (2)ServerSocket对象.accept() 监听来自客户端的连接 连接成功时建立Socket连接对象 请求连接 (1)为客户机创建Socket对象 注册服务器地址和端口,请求连接 连接成功时建立Socket连接对象 连接成功 (3)用Socket连接创建流对象:OutputStream和 InputStream (2)用Socket连接创建流对象:OutputStream和 InputStream (4)通过流进行通信数据处理 用InputStream对象发送数据 用OutputStream接受数据 创建ServerSocket对象对象 传送数据 (3)通过流进行通信数据处理 用InputStream对象发送数据 用OutputStream接受数据 创建ServerSocket对象对象 (5)关闭连接,关闭Stream (4)关闭连接,关闭Stream 13.3.4 基于流套接字的客户/服务器的通信过程
13.3.4 基于流套接字的客户/服务器的通信过程 • 例子说明如何建立服务器的应用和客户机的应用。 例13-6 服务器端的应用. 运行输出结果: 例13-7 客户端的应用.运行输出结果:
13.3.5 多线程实现多用户网上聊天 • 实现多用户网上能同时聊天,由于存在单个服务器程序与多个客户程序通讯的可能,要求: l服务器程序响应客户程序不应该花很多时间,否则客户程序在得到服务前有可能花很多时间来等待通讯的建立 l还有,服务程序和客户程序的会话有可能是很长的(与电话类似) • 为了加快对客户程序连接请求的响应,典型的方法: • 服务器主机在响应每一个客户连接请求时运行一个后台通信服务线程, • 这个后台线程处理和客户程序之间的通讯。 • 又由于在服务器主机上创建每一个后台通信服务线程,都需要花费一定的主机资源,因此对允许与服务器连接的客户数应有一个限制。
13.3.5 多线程实现多用户网上聊天 例13-8 服务器聊天程序的实现. • ChatServer.java声明了一个外部类ChatServer 和一个内部类CommunicationThread。 • 在ChatServer类的main()方法:创建了一个ChatServer对象,并通过调用构造方法来创建ServerSocket对象,以监听端口50000上的连接请求,如果连接成功, ChatServer进入一个无限循环中,交替调用ServerSocket的accept() 方法来等待连接请求,同时启动后台线程处理连接(accept()返回的请求)。 • 后台线程由CommunicationThread继承的start()方法开始,并执行CommunicationThread的run()方法中的代码。 一旦run()方法运行,线程将向当前连接的客户应用发送用户号clientID,接着循环读此用户发送来的聊天信息,并转发给当前参与聊天的各个用户,直到此用户发出信息“stop chat”为止。 • 运行ChatServer.class后,就可以运行多个ChatClient程序。
13.3.5 多线程实现多用户网上聊天 例13-9 客户端聊天程序的实现. • 客户端聊天程序是一个Applet。功能: • 提供客户聊天界面,用于输入信息和显示信息; • 接受通过服务器转发的其它客户聊天信息并显示。 • 两个客户端聊天程序的界面:
13.4 基于数据报套接字方式的客户/服务器通信 • 数据报套接字: • 无连接的的数据传递方式。 • 它的传输速度快, • 但不能保证所有数据都能到达目的地,所以一般用于非重要的数据传输。 • 与数据报套接字相关的有三个类,位于java.net包。 • DatagramPacket类:用来创建数据包 • DatagramSocket:用于发送和接收数据包的套接字 • MulticastSocket:描绘了能进行多点传送的套接字,
13.4.1 DatagramPacket类 • 使用数据报方式首先将数据打包. DategramPacket类用来创建数据包。 数据包分有两种: • 要发送数据的数据包,该数据包有要到达的目的地址; • 用来接收数据的数据包。 (1)要创建接受数据包,使用DatagramPackett类的构造方法: DatagramPacket(byte ibuft[],int ilength) ibuf[]:接受数据包的存储数据的缓冲区, ilength:从传递过来的数据包中读取的字节数。
13.4.1 DatagramPacket类 (2)要创建发送数据包,使用DatagramPacket类的构造方法: DatagramPacket(byt ibuf[],int ilength,InetAddrss iaddr,int port) ibuf:要发送数据的缓冲区; ilength:发送数据的字节数; iaddr:数据包要传递到的目标地址; iport:目标地址的程序接受数据包的端口号。
13.4.1 DatagramPacket类 • DatagramPacket数据包对象的操作方法,以获取数据包的信息: (1)netAddrss getAddrss() 获得数据包要发送的目标地址 (2)byte[]getData() 获得数据包中的数据 (3)public int getLength() 获得数据包中数据的长度 (4)int getPOrt( ) 获得数据包中的目标地址的主机端口号
13.4.2 DatagramSocket类 • 发送和接收数据包,需要发送和接收数据包的DatagramSocket对象,用DatagramSocket类构造此对象。 • DatagramSocket类的构造方法如下: (1)Datagramsocket(): 用本地机上任何一个可用的端口,创建一个发送或接收数据包的套接字。 (2)DatagramSocket(int port) 用一个指定的端口,创建一个发送/接受数据包的套接字。
13.4.2 DatagramSocket类 • DatagramSocket对象的方法: (1) void receive(Datagrampacket p) :接收数据包。 (2) void send(DatagramPacket p):发送数据包。 (3) int getLocalPort( ):得到本地机的端口。
13.4.3 基于数据报套接字的客户/服务器的通信应用实例 • 基于数据报套接字的方式下,服务器应用程序和客户机应用程序之间发送和接收信息。完成的功能: • 在客户端应用程序中,用户在文本框中输入一行信息,按下回车键后,会将此行信息发送到服务器上。 • 服务器接受到此信息后,将此信心在服务器的GUI界面上显示,并完成将此行信息发回到客户机上。 • 客户即收到此信息后,即将此信息显示。
例13-10服务器应用程序的实现. Server.java中完成: • 构造方法: • 建立了GUI界面,显示接收到的数据包, • 建立了的服务器套接字DatagramSocket对象,并将服务器套接字绑定在端口5000上。 • 方法waitForPackets(),用无限循环等待客户发送过来的数据分组。 • 建立一个接收数据包DatagramPacket对象, • 用socket的方法receive等待数据包到达服务器,此方法的调用一直阻塞,直到分组到来,则将分组存储到receivePacket中。 • 接着调用方法displayMessage,将分组信息显示。 • 调用sendPacketToClient()将服务器接收到的分组发回到客户机。 • 方法sendPacketToClient( DatagramPacket receivePacket ) • 创建发送数据包 DatagramPacket对象sendPacket, 然后调用socket的方法send将数据包发送出去。 • 在main方法: • 创建服务器应用程序类Server的对象, • 调用方法waitForPacket(),等待客户发送过来的数据分组。
例13-11客户机应用程序的实现。 客户应用程序类Client.java完成的任务: • 构造方法:建立了GUI界面供输入信息和显示接收到的数据包。 • 建立了的套接字DatagramSocket对象。 • 在输入文本字段的事件处理代码actionPerformed方法中 • 取用户输入的信息,创建要发送给服务器的数据包,在此构造数据包对象时,将服务器的主机地址和端口号捆绑。接着用DatagramSocket对象的方法send()发送数据包。 • 方法waitForPackets(),用无限循环等待服务器发送过来的数据分组。 • 首先建立一个接收数据包DatagramPacket对象,用socket的方法receive等待数据包到达服务器,此方法的调用一直阻塞,直到分组到来,则将分组存储到receivePacket中。 • 接着调用方法displayMessage,将分组信息显示。 • 在main方法: • 先创建客户应用程序类Client的对象, • 调用方法waitForPackets(),等待服务器发送过来的数据分组。
小结 • Java提供的网络功能按层次使用分为:URL、流套接字和数据报套接字。 • URL类:为访问网络资源提供的API接口,利用URL对象中的方法可以直接读取网络中的资源; • URLConnection类:可双向访问(及可读可写)网络上的资源。 • 流套接字:面向连接的网络服务,用于传送的协议是TCP协议。 • 数据报套接字:无面向连接的网络服务,传送的协议是UDP协议。
习题 • 1,2,3,4 • 实验20
[作业] 书上本章习题中: 3. 4. 5. 6. 7. 8. 9.