• 1. 11.Java网络通信周筱媛 西安科技大学 计算机系 Email: yuanyuanzhou@hotmail.com Tel: 13072904364
  • 2. 主要内容:学习如何通过java.net包中的类直接在程序中实现网络通信。
  • 3. 11.1 URL类编程 URL(Uniform Resource Locator)是统一资源定位器的简写。它表示Internet上某一资源的地址,这些资源包括Web页、文本文件、图形(像)文件和声频片段等。通过URL可以访问Internet和WWW。浏览器通过解析给定的URL可以在网络上查找相应的文件或资源。
  • 4. 11.1.1 URL的组成和URL类 URL的组成 protocol ://resourceName 协议名指明获取资源所使用的传输协议,如http、ftp等; 资源包括主机名、端口号、文件的引用; 如 http://www.xust.edu.cn http://localhost:8080/jsp/temp.html 协议名 资 源
  • 5. URL类 Java将URL封装成URL类,通过构造方法可以实例化一个URL对象。 public URL(String spec) public URL( URL url, String file) public URL(String protocol, String host, String file) public URL(String protocol, String host, int port, String file) URL myURL = new URL(“http://www.xust.edu.cn”);URL mydoc = new URL(myURL, “index.html”);URL myURL = new URL(“http”, “www.sohu.com”, “index.html”);URL myURL = new URL(“http”, “www.sohu.com”, 80,“index.html”);
  • 6. URL类编程中的常见异常 MalformedURLExceptiontry{ …… URL myURL = new URL(“……”); …… }catch(Exception e){ …… //异常处理 …… }
  • 7. URL类的成员方法: public final Obect getContent(); public String getFile(); public String getHost(); public int getPort(); public String getProtocol(); public String toExternalForm(); public String toString(); public final InputStream openStream() throws ……; public URLConnection openConnection(); ……
  • 8. 例1 获取URL对象属性 import java.net. *; public class myurl{ pub1ic 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.getFle()); System.out.println("the ext: "+url.toExternalForm)), System. out. println(url. toString()); } catch(Exception e){ System.out.println(e); } } } the protocol:http the hostname: www. tsinghua. edu. cn the port:80 the file: /homelhomepage. html the ext: http://www.tsinghua. edu. cn: 80/home/homepage .html http://www.tsinghua. edu. cn: 80/home/homepage .html
  • 9. 使用URL类读取WWW信息 通过openStream()与指定的URL建立连接并返回一个InputStream类的对象,然后从这一连接中读取数据。 常用的读取网络资源数据的步骤如下: 创建URL类的实例对象; 通过URL类的实例对象的openStream方法建立连接; 读取数据; 关闭数据流;
  • 10. 例2 用url.openStream()方法读取WWW数据 import java.net.*; import java.io.*; public class OpenStream{ public static void main(String args[]) throws Exception{ URL url=new URL("http://www.xust.edu.cn"); BufferedReader in=new BufferedReader( new InputStreamReader(url.openStream())); String inputLine; while((inputLine=in.readLine())!=null){ System.out.println(inputLine); } in.close(); } }
  • 11. 使用URLConnection连接WWW URLConnection的对象表示Java程序与URL在网络上的通信连接。 使用URLConnection对象获取WWW资源的步骤: 创建一个URL对象; 调用URL对象的getConnection()方法获得对应的URLConnection对象; 获取输入流并读数据; 关闭连接;
  • 12. 例3 使用URLConnection连接服务器 import java.net. *; import java.io. *; public class urlcon{ public static void main(String args[]){ InputStream is; OutputStream os; int b; try{ URL url=new URL("http://www.xust.edu.cn"); URLConnection uric= url.openConnection(); System.out.println("the length:"+uric.getContentLength()); System.out.println("the type:"+uric.getContentType()); System.out.println("the date: "+uric.getDate()); System.out.println("the lastmodified:"+uric.getLastModified()); os=new FileOutputStream("d:\\down.html" );if(uric.getContentLength()>=1){ is=uric.getInputStream(); while((b=is.read())!= -1){ os.write(b); System.out.write(b); } }else{ System.out.println("no content"); } }catch(Exception e){ System.out.println(e); } } }
  • 13. 例11.5 利用URLConnection向服务器发送查询信息,并接受服务器返回的参数。 P254
  • 14. 二、Socket通信预备知识 Socket是网络上的两个程序通过一个双向的通信连接实现数据交换的通道。或者说网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,可以说Socket是面向客户/服务器模型设计的。Socket通信机制提供了两种通讯方式:有联接(TCP)和无联接(UDP)方式,分别面向不同的应用需求。 TCP是以连接为基础的流式协议,通信前,首先要建立连接,然后才能通信。因此,能保证同步、准确地进行通信。如果应用程序需要可靠的点对点通信,一般采用TCP这种协议。比如:HTTP,ftp,telnet等应用程序,确保其可靠性对于程序运行是非常关键的。
  • 15. UDP是一种无连接的协议,其系统开销比无联接方式小,但通信链路提供了不可靠的数据报服务,每个数据报都是一个独立的信息,不能保证信源所传输的数据一定能够到达信宿。在该方式下,通信双方不必创建一个联接过程和建立一条通讯链路,网络通信操作在不同的主机和进程之间转发进行。 端口: 数据通过网络到达一台主机(或准确的说是主机的网卡)是通过IP地址实现的。但当该主机运行多个程序时如何识别数据是属于哪个程序的呢? 这就是端口。一个端口只能绑定一个应用程序。通过TCP/UDP通信的应用程序必须知道对方的IP地址和端口号才能通信。端口号可取从0-65535,其中,0-1023为保留端口,提供给众所周知的一些服务。
  • 16. Socket通信的一般过程 使用Socket进行客户/服务器通信程序设计的一般过程是这样的: Server端listen(监听)某个端口是否有连接请求, Client端向Server端发出connect(连接)请求, Server端向Client端发回Accept(接受)消息。 一个连接就建立好了,之后客户端、服务器端都可以用send()、write()等方法与对方通信。
  • 17. 对于一个功能齐全的Socket的工作过程包含以下四个基本步骤: 创建Socket; 打开连接到Socket的输入输出流; 按照一定的协议对Socket进行读/写操作; 关闭Socket。
  • 18. 1.创建Socket 创建客户端Socket可以通过Socket的构造方法,介绍如下:  public Socket(String host,int port) public Socket(InetAddress address,int port) // 用该方法创建一个与指定远程主机及其端口建立连接; public Socket(String host,Int port,boolean stream) // stream指明Socket是流式Socket还是数据报式Socket public socket(InetAddress address,Int port,boolean stream) Serversocket的构造方法为: public Serversocket(int port) //指定端口号来创建Serversocket对象,该端口为端主机的端口; public Serversocket(int port,int count) //用指定的端口号创建Serversocket对象,如果该端的端口正在使用,只等待count毫秒。
  • 19. 2. 打开输入/输出流 public Inputstream getInputstream( ) //得到 Socket建立的输入流 pubic Outputstream getoutputstream( ) //得到 Socket建立的输出流 Socket对象的其他方法: public void close() public InetAddress getlnetAddress() //得到远程主机 IP地址的 InetAddress对象 public int getLocalPort() //得到与远程机连接的本地机的端口号
  • 20. Serversocket对象的其他方法:  public Socket accept() //获取与客户端连接的 Socket对象 //accept()为一个阻塞性方法,即该方法被调用后,将等待客户的请求,直到有一个客户启动并请求连接到相同的端口,然后accept()返回一个对应于客户的Socket。 public void close() public InetAddrss getInetAddress() // 得到与客户端相连的 InetAddress对象 public int getLocalPort() // 得到服务器在监听的端口号
  • 21. 例11.3 P241 例11.4 P243
  • 22. 1) 客户端的编程流程:   打开Socket,新建一个套接字;   为套接字建立一个输入和输出流;   根据服务器协议从套接字读入或向套接字写入;   清除套接字和输入/输出流; 2)服务器端的编程流程:  打开Server Socket,创建一个服务器型套接字和一个普通套接字,服务器型套接字在指定端口为客户端请求的Socket服务;  使用ServerSocket类的accept()方法使服务器型套接字处于监听状态并把监听结果返回给普通套接字;  为该普通套接字创建输入和输出流;  从输入和输出流中读入或写入字节流,进行相应的处理,并将结果返回给客户端;  在客户端和服务器工作结束后关闭所有的对象,如服务器型的套接字,普通套接字,输入和输出流。 小结:
  • 23. 三、数据报通信 数据报(Datagram)使网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址信息的消息,它能否到达目的地,到达的时间,到达时内容是否会变化不能准确知道的。它的通讯双方是不需要建立连接的,对于一些不需要很高质量的应用程序来说,数据报通讯是一个非常好的选择。 在Java的java.net包中有两个类DatagramSocket和DatagramPacket用来支持数据报通信。
  • 24. DatagramSocket的构造方法:  public DatagramSocket() //构造一个数据报socket,并使其与本地主机任一可用的端口连接。若打不开socket则抛出SocketException异常。 public DatagramSocket(int port) //构造一个数据报socket,并使其与本地主机指定的端口连接。若打不开socket或socket无法与指定的端口连接则抛出SocketException异常。
  • 25. DatagramPacket的构造方法:  DatagramPacket( byte bufferedarray[ ], int offset, int length, InetAddress address, int port) //构造一个包长度为length的包传送到指定主机指定端口号上的数据报文包,参数length必须小于等于bufferedarry.length DatagramPacket( byte bufferedarray[ ], int length) //接收从服务器返回的结果数据报文 ,只需指明存放接收的数据报的缓冲区和长度。
  • 26. 在Java中实现客户端与服务器之间数据报通讯的方法 : 客户端应用程序的工作流程 建立数据报通讯的Socket,我们可以通过创建一个DatagramSocket对象来实现它。 创建一个数据报文包,用来实现无连接的包传送服务。每个数据报文包是用DatagramPacket类来创建,DatagramPacket对象封装了数据报包数据,包长度,目标地址,目标端口。作为客户端要发送数据报文包,要调用DatagramPacket类的构造方法创建DatagramPacket对象,将要发送的数据和包文目的地址等信息放入对象之中。
  • 27. 创建完DatagramSocket和DatagramPacket对象,就可以发送数据报文包了。发送是通过调用DatagramSocket对象的send方法实现,它需要以DatagramPacket对象为参数,将刚才封装进DatagramPacket对象中的数据组成数据报发出。 也可以接收数据报文,为了接收从服务器返回的结果数据报文,需要创建一个新的DatagramPacket对象,调用DatagramSocket对象的receive()方法来完成接收数据报的工作,此时需要将上面创建的DatagramPacket对象作为参数,该方法会一直阻塞知道收到一个数据报文包,此时DatagramPacket的缓冲区中包含的就是接收到的数据,数据报文包中也包含发送者的IP地址,发送者机器上的端口号等信息。
  • 28. 建立数据报通讯的Socket,我们可以通过创建一个DatagramSocket对象来实现它。 处理接收缓冲区内的数据,获取服务结果。 当通讯完成后,可以使用DatagramSocket对象的close()方法来关闭数据报通讯Socket。当然,Java自己会自动关闭Socket,释放DatagramSocket和DatagramPacket所占用的资源。但是作为一种良好的编程习惯,还是要显示的予以关闭。
  • 29. 服务器端应用程序的工作流程 不同于基于数据流通讯方式,在数据报通讯中,通讯双方之间并不要建立连接,所以,服务器应用程序通讯过程与客户端应用程序的通讯过程使非常相似的,也要建立数据报通讯DatagramSocket,构建数据报文包DatagramPacket,接收数据报和发送数据报,处理接收缓冲区内的数据,通讯完毕后,关闭数据报通讯Socket。不同的是,服务器应用程序要面向网络中的所有计算机,所以服务器应用程序收到一个包文后要分析它,得到数据报的源地址信息,这样才能创建正确的返回结果报文给客户机。