1、第 6章 网络编程学习导读本章将介绍 Java网络编程技术和传输协议,包括:高层基于 URL编程基于 Socket编程基于 Datagram编程其中基于 Socket套接字的网络编程及 I/O流操作是重点 .*Java程序 设计 与开 发6.1 Java网络基础 6.1.1 IP地址 6.1.2 端口 6.1.3 套接字 6.1.4 数据报 6.1.5 传输协议 6.2 基于 URL的高层次 Java网络编程6.2.1 从 URL中读取内容 6.2.2 建立 URL连接并读取内容 6.3 基于 Socket的网络编程 6.3.1 Socket通信过程 6.3.2 创建客户端 Socket 6.
2、3.3 创建服务器端 Socket 6.3.4 打开输入输出流 6.3.5 关闭流和 Socket 6.4 基于 Datagram的网络编程 6.4.1 数据报和套接字 6.4.2 创建客户端 Datagram 6.4.3 创建服务器端 Datagram 6.4.4 打开输入输出流 6.4.5 关闭流和 Datagram第 6章 网络编程DateJava程序 设计 与开 发6.1 网络基础知识v IP地址如: 136.111.136.3, 192.111.52.80v 主机名 (hostname)如, localhost, iprai10 IP主机名 , InetAddress类 还有域名,
3、v 端口号 (well-known ports, dynamic ports)允许范围 : 065535, 自定义端口使用 102465535按端口号划分, 如 :HTTP-80, FTP-21, Telnet-23, SMTP-25按协议,如 TCP端口, UDP端口DateJava程序 设计 与开 发v 套接字 (Socket)是 就是通信双方的一种约定,通信双方需要建立连接 。 Java将套接字抽象化为类 ,程序设计者只需创建Socket类对象,即可使用套接字进行编程。v 数据报 (Datagram)方式 不事先建立连接 ,服务程序将要传递的数据打包,分成一个个小的数据包,每个数据包都有
4、它要送达的计算机地址。数据包被发送后, 并不能够保证它一定能够到达目的地址 。套接字DateJava程序 设计 与开 发传输协议v TCP (Transport Control Protocol )面向连接的能够提供可靠的流式数据传输的协议。类似于打电话的过程。URL, URLConnection, Socket, ServerSocket等类都使用 TCP协议进行网络通讯。v UDP (User Datagram Protocol )非面向连接的提供不可靠的数据包式的数据传输的协议。类似于从邮局发送信件的过程。DatagramPacket, DatagramSocket, Multicast
5、Socket等类使用 UDP协议进行网络通讯。 DateJava程序 设计 与开 发v Java网络类库支持多种 Internet协议,其中包括 Telnet、FTP和 HTTP,相对应的 Java类库的子类库如下所示:.*如, .FTP.www.*如, .www.http 这些类库各自包含了用于处理 Internet协议的类和方法。DateJava程序 设计 与开 发6.2 基于 URL的高层网络编程v URL(Uniform Resource Locator)一致资源定位器的简称,它表示 Internet上某一资源的地址。v URL由 3部分组成:协议名 :/主机名 :端口号 /文件名,例
6、如http:/localhost:80/iisstart.asp协议名指明获取资源所使用的传输协议,如 http、 ftp、gopher、 file等,资源名则应该是资源的完整地址,包括主机名、端口号、文件名或文件内部的一个引用。v 抽象类 URLConnection,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源,可以由 URL对象创建 .DateJava程序 设计 与开 发1. 从 URL中读取内容a. URL类提供多种不同的构造方法,用于以不同形式创建URL对象。 public URL(String spec) throws Malformed
7、URLException public URL(URL context, String spec) throws MalformedURLException public URL(String protocol, String host, String file) throws MalformedURLException public URL(String protocol, String host, int port, String file) throws MalformedURLException 其中 ,参数 spec是由协议名 ,主机名 ,端口号 ,文件名组成的字符串 .参数 con
8、text是已建立的 URL对象 ,参数 protocol是协议名 ,参数 host是主机名 ,参数 file是文件名 ,对数 port是端口号 . 注意, URL类的构造方法都抛出 MalformedURLException异常 . DateJava程序 设计 与开 发v 例如,下面通过各种构造方法创建 URL对象,分别以不同的方式提供 URL地址的各部分信息: URL myURL1=new URL(“http:/ URL myURL2=new URL(myURL1,“research/zrkx.jsp”); URL myURL3=new URL(“http”,“”,“index.jsp”);
9、 URL myURL4=new URL(“http”,“”,80,“index.jsp”); 上面的 myURL2地址是由 myURL1地址和用相对路径表示的文件名会成的,代表的 URL地址是:http:/ 设计 与开 发b.如果成功建立了一个 URL对象,就可以利用 URL对象的不同方法来读取其中的各种内容属性。但属性不能被改变:public String getProtocol() /获取 URL的协议名 public String getHost() /获取 URL 的主机名 public int getPort() /获取 URL的端口号 public String getPath()
10、 /获取 URL的文件路径 public String getFile() /获取 URL的文件名 public String getRef() /获取 URL在文件中的相对位置public String getQuery() /获取 URL的查询名 还可以用来打开一个连接,获取输入流等方法: public URLConnection openConnection() /返回一个 URLConnection 对象 public InputStream openStream() /打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream DateJava程序 设计 与开 发2
11、.建立 URL连接并读取内容首先创建一个 URL对象,然后使用它的 openConnection()方法生成一个相应的 URLConnection对象来建立连接。成功建立连接之后,就可以使用这个 URLConnection对象执行这些操作。主要方法有:public InputStream getInputStream() /获取输入流对象public OutputStream getOutputStream() /获取输出流对象下面举例说明 .【 例 6.1】 使用 URL对象打开连接和输入流DateJava程序 设计 与开 发程序运行结果DateJava程序 设计 与开 发3.利用 URL访
12、问网上资源 一个 URL对象对应一个网址,生成 URL对象后,也可以调用URL对象的 openStream()方法读取网页内容等信息。下面举例说明 .【 例 6.2】 使用 URL对象直接打开流DateJava程序 设计 与开 发程序运行结果 ?DateJava程序 设计 与开 发也可以使用 BufferedReader方法将原始的 InputSream输入流转变为其他类型的输入流程序运行结果 ?DateJava程序 设计 与开 发6.3 基于 Socket的网络编程v 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个 Socket。 Socket通常用来实现客
13、户端和服务器之间的连接。v 客户端使用 Socket类与服务器的某个端口建立连接,服务器程序则需要初始化一个端口进行监听,遇到客户端的连接请求才与相应的客户端建立连接。v 一个服务器可以监听多个客户端的连接请求并与之建立连接,然后完成 I/O操作。下面是基于 Socket的编程模型 .DateJava程序 设计 与开 发Socket 编程模型客户端套接字创建套接字 服务器套接字客户端 服务器读写数据读写数据关闭流 ,套接字关闭流 ,套接字等待请求 连接接受连接发送 I/O流接收接收发送关闭 拆除连接关闭DateJava程序 设计 与开 发TCP Socket通讯过程v 采用 TCP通讯方式开发
14、 服务器与客户端程序的主要步骤:- 初始化服务器,建立 ServerSocket对象,等待客户端的连接请求 ; 初始化客户端,建立 Socket对象,向服务器发起连接请求 ; 服务器响应客户端,建立连接 ; 客户端发送请求数据到服务器 ; 服务器接收客户端请求数据 ; 服务器处理请求数据,并返回处理结果给客户端 ; 客户端接收服务器返回的结果 ; 重复步骤,直到一端请求关闭连接 ; 服务器和客户端关闭连接,结束通讯-DateJava程序 设计 与开 发1.服务器程序 的编写(1)调用 ServerSocket类,在指定的监听端口创建一个ServerSocket对象 ;(2)ServerSock
15、et对象调用 accept()方法在指定的端口监听到来的连接,该方法阻塞当前线程,直到收到客户端连接请求,并返回一个 Socket对象 (连接客户端与服务器 );(3)调用 getInputStream()方法和 getOutputStream()方法获得Socket对象的输入流和输出流 ;(4)服务器与客户端按照约定的协议交互数据,直到一端请求关闭连接 ;(5)服务器关闭和客户端通讯的流和通讯 Socket;(6)服务器回步骤 (2),继续监听下一次的连接,而客户端则结束运行。DateJava程序 设计 与开 发v ServerSocket构造方法及其重载ServerSocket() thr
16、ows IOException /创建非绑定服务器套接字ServerSocket(int port) throws IOException /创建绑定到特定端口的 ServerSocket(int port, int backlog) throws IOException; /利用指定的 backlog 创建 ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException /使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器在以上构造方法中,参数 port指定服务器要绑定的端口(
17、要监听的端口),参数 backlog指定客户连接请求队列的长度,参数 bindAddr指定服务器要绑定的 IP地址。DateJava程序 设计 与开 发例如,ServerSocket ss =new ServerSocket(8000); 如果运行时无法绑定到 8000端口,上述语句会抛出 IOException,更确切地说,是抛出 BindException,它是 IOException的子类。v ServerSocket类的其他重要方法public Socket accept(); /侦听并接受到此套接字的连接 public void bind(SocketAddress endpoint
18、) /将 ServerSocket绑定到特定地址 (IP 地址和端口号 ) public InetAddress getInetAddress(); /返回将此套接字绑定到的地址 public void close(); /关闭此套接字 DateJava程序 设计 与开 发v 例如,创建服务器套接字ServerSocket sst=new ServerSocket(8080);Socket st=sst.accept(); /下面进行 I/O流读写 或者,Socket fromClient; int count=0; ServerSocket sst=new ServerSocket(8080
19、);while(true) fromclientcount= sst.accept(); count+; DateJava程序 设计 与开 发2.客户端程序 的编写(1)调用 Socket类的构造方法,以服务器主机地址和端口号为参数,创建一个 Socket对象,这个过程包含了一个向服务器请求建立通讯链路 ;(2)利用 Socket对象提供的数据读写方法 getInputStream()和getOutputStream()得到对应的输入 /输出流对象,以进行读写操作,网络 I/O转变为使用流的过程 ;(3)使用流对象的方法读写字节流数据,为便于读写数据,可在返回的输入 /输出流对象上建立过滤流。
20、例如,DataInputStream, DataOutputStream或 PrintStream类对象。(4)数据传输完毕,关闭所有与 Socket相关的输入 /输出流,关闭连接。DateJava程序 设计 与开 发v Socket构造方法及其重载protected Socket(SocketImpl impl) 使用用户指定的 SocketImpl 创建一个未连接 Socket public Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号 public Socket(String host, int port, InetAdd
21、ress localAddr, int localPort) 创建一个套接字并将其连接到指定远程主机上的指定远程端口 public Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号 public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 创建一个套接字并将其连接到指定远程地址上的指定远程端口可能抛出的异常有: UnknownHostException, IOException, SecurityExce
22、ption。若 host值为 null,表示回送地址。DateJava程序 设计 与开 发v 例如,创建客户端 Socket对象trySocket socket=new Socket (“127.0.0.1”, 2000);catch(IOException e)System.out.println(“Error:“+e);v 一旦成功建立连接,接下来就可以打开输入、输出流进行I/O 操作了。DateJava程序 设计 与开 发v 可使用下述方法打开输入、输出流PrintStream ps=new PrintStream (new BufferedOutputStream (socket.ge
23、tOutputStream();DataInputStream dis=new DataInputStream (socket.getInputStream();PrintWriter pw=new PrintWriter (socket.getOutputStream, true);BufferedReader br=new BufferedReader (new InputStreamReader (socket.getInputStream();v 先关闭流,再关闭 socketps.close();dis.close();pw.close();Socket.close(); 下面举例说
24、明之 .【 例 6.3】 使用 TCP Socket编写服务器和客户端程序DateJava程序 设计 与开 发(1) 聊天服务器程序程序运行结果 ?DateJava程序 设计 与开 发(2)聊天客户端程序程序运行结果 ?DateJava程序 设计 与开 发程序运行结果v 注意: 不要混淆了 ServerSocket对象 和 由 accept()方法返回的 socket对象 的关闭。关闭了 accept()方法返回的 socket对象只是结束了服务器和 当前客户端 的连接,服务器不再为这个客户端服务,但它可以 继续接受其他客户端 的连接请求,并为它提供服务。关闭 ServerSocket对象意味着服务器将退出,不再为任何客户端提供服务 !DateJava程序 设计 与开 发v 如果再打开一个窗口运行客户端程序,如图所示:v 想想看,为什么不能响应 多个客户端 ?如何设计才能完成此目标?另外,上述服务器和客户端之间处于 “问答式 ”聊天,如何改进?v 上述聊天服务器实际处于 单例工作方式 ,还有另一种是 并发工作方式 .Date