JavaSE第一百零七讲:使用Java网络API访问远程服务器

来源:互联网 发布:原油数据公布的网站 编辑:程序博客网 时间:2024/06/05 09:05

    上一讲内容中,我们大概介绍了网络中的基本知识,其中的TCP和UDP是比较重要的内容。在这一讲中我们重要讲解使用Java网络API访问远程服务器。

1. UDP

  UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的

  UDP是从一台计算机向另一台计算机发送称为数据报的独立数据包的协议,该协议并不保证数据报是否能正确地到达目的地。它是一个非面向连接的协议

 一般在视频会议中它是UDP来实现的,因为视频会议传输数据量大(它是一种动态的影像),如果使用TCP协议来作为传输协议,它需要校验连接等这些内容。这显然是不符合场景的,所以如果数据量比较大、准确性不太高,可以使用UDP来进行传输。

 其实TCP,UDP要想真正理解是有很多内容的,张龙老师给我们推荐的一本书《TCP详解》有三卷。

2. 比较一下TCP和UDP这两类传输协议(TCP与UDP之间的差异性直接决定了它们编程模型的差异性)

1)使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

2)对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间

3) 使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。

4)TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。

5)UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

6)TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据

7) TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。

8)相比之下UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序

3. 既然有了保证可靠传输的TCP协议,为什么还要非可靠传输的UDP协议呢?

主要的原因有两个。
  一是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高
  二是在许多应用中并不需要保证严格的传输可靠性,比如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些.

4. 端口

  1)在互联网上传输的数据都包含有用来识别目的地的IP地址和端口号。IP地址用来标识网络上的计算机,而端口号用来指明该计算机上的应用程序


  2) 端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序通过系统调用与某端口建立连接(binding)后,传输层传给该端口的数据都被相应的进程所接收,相应进程发给传输层的数据都通过该端口输出。

  3)端口用一个整数型标识符来表示,即端口号。端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立,端口通常称为协议端口(protocol port) ,简称端口。

  4)端口使用一个16位的数字来表示,它的范围是0~65535,1024以下的端口号保留给预定义的服务。例如:http使用80端口。

5. 数据封装

  1)一台计算机要发送数据到另一台计算机,数据首先必须打包,打包的过程称为封装。
  2) 封装就是在数据前面加上特定的协议头部。

3) OSI参考模型中,对等层协议之间交换的信息单元统称为协议数据单元(PDU,Protocol Data Unit)。

4)OSI参考模型中每一层都要依靠下一层提供的服务。

5)为了提供服务,下层把上层的PDU作为本层的数据封装,然后加入本层的头部(和尾部)。头部中含有完成数据传输所需的控制信息。

6)这样,数据自上而下递交的过程实际上就是不断封装的过程。到达目的地后自下而上递交的过程就是不断拆封的过程。由此可知,在物理线路上传输的数据,其外面实际上被包封了多层“信封”。

7)但是,某一层只能识别由对等层封装的“信封”,而对于被封装在“信封”内部的数据仅仅是拆封后将其提交给上层,本层不作任何处理。

6. TCP/IP模型包括4个层次:

应用层
传输层
网络层
网络接口

TCP/IP与OSI参考模型的对应关系

7.以上就是介绍的网络的基本知识,现在我们就可以通过JDK中的网络类来进行一些代码编写

1)通过java.net包中的类,java程序能够使用TCP或UDP协议在互联网上进行通讯
2) Java 通过扩展已有的流式输入/输出接口和增加在网络上建立输入/输出对象特性这两个方法支持TCP/IP。
3) Java支持TCP和UDP协议族。TCP用于网络的可靠的流式输入/输出。UDP支持更简单的、快速的、点对点的数据报模式

8.创建和使用URL访问网上资源

  1)URL(Uniform Resource Locator)是统一资源定位符的简称,它表示Internet上某一资源的地址。通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW,FTP站点。浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源。

  2) URL是最为直观的一种网络定位方法。使用URL符合人们的语言习惯,容易记忆,所以应用十分广泛。而且在目前使用最为广泛的TCP/IP中对于URL中主机名的解析也是协议的一个标准,即所谓的域名解析服务。使用URL进行网络编程,不需要对协议本身有太多的了解,功能也比较弱,相对而言是比较简单的。

  3)一个URL 包括两个主要部分:

协议标识符:HTTP,FTP,File等,[注意在浏览器中我们可以打http开头,因为浏览器帮会默认帮我们补上http标识符,但是其它的标示符还是要写上去的]
资源名字:主机名,文件名,端口号,引用
例如:http://java.sun.com:80/docs/books/tutorial/index.html#DOWN[http应用默认的端口号是80,如果不80,它也会指定到80,但是如果对方的主机服务器没有把监听的端口号设置为80,则这边也必须显示的指定好统一的端口号]

  4) 创建URL:在Java程序中,可以创建表示URL地址的URL对象。URL对象表示一个绝对URL地址,但URL对象可用绝对URL、相对URL和部分URL构建

  5) 程序Demo:

package com.ahuier.network;/* * 查看JDK 文档中的URL类,及相关的构造方法,和定义的方法 * 我们主要是用第一种构造方法:public URL(String spec) throws MalformedURLException */import java.net.URL;public class Url1 {public static void main(String[] args) throws Exception {//注意这边并不一定要是一个合法的网络地址,它并不会联网URL url = new URL("http://java.sun.com:80/docs/books/tutorial/index.html#DOWN");String protocol = url.getProtocol();String host = url.getHost();String file = url.getFile();int port = url.getPort();String ref = url.getRef();System.out.println(protocol + " ," + host + ", " + file + ", " + port + ", " +ref);}}
编译执行结果:

http ,java.sun.com, /docs/books/tutorial/index.html, 80, DOWN

说明】:URL也可以看做是网络编程的入口,基本上都是从URL开始的,因为我们想要访问一个地址,肯定要构造一个URL对象的,另外一些API的使用可以去参考JDK文档。

9.单纯的使用URL,其实意义不是非常大,通常我们是构建一个URL对象,然后通过URL的这个对象访问到远程到机器主机的信息,相对比较重要的,所以要进行与远程服务器的连接。

1)为获得URL的实际比特或内容信息,用它的openConnection()方法从它创建一个URLConnection对象,如下:
   url.openConnection()

2)openConnection()有下面的常用形式:
   URLConnection openConnection()

3)与调用URL对象相关,它返回一个URLConnection对象。它可能引发IOException异常

4)URLConnection是访问远程资源属性的一般用途的类。如果你建立了与远程服务器之间的连接,你可以在传输它到本地之前用URLConnection来检察远程对象的属性。这些属性由HTTP协议规范定义并且仅对用HTTP协议的URL对象有意义

查看JDK文档URL类的openConnection()方法,它是打开连接

  public URLConnection openConnection() throws IOException

返回一个URLConnection对象。换句话说它是已经和远程连接建立好,并且已经打开了,打开之后,像HTTP,FTP都是基于TCP的要以IO的方式,流的方式进行交互,双向的传递。

继续查看URLConnection类的定义方法
  public InputStream getInputStream()throws IOException
  public OutputStream getOutputStream() throws IOException

这样它就可以与远程资源进行连接的输入流,通过这个流就得到字节数据。获得到流之后就可以通过I/O编程获得到远程的信息了。

 5) 程序Demo:

package com.ahuier.network;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.URL;import java.net.URLConnection;/* * 获取到远程信息,所以连接到 网址:http://infoq.com 必须是真是存在的 * 连接到网页首页之后,就可以获取它的网页信息了 */public class UrlConnnection1 {public static void main(String[] args) throws Exception {URL url = new URL("http://infoq.com");//打开连接,获取到远程URL进行连接的URL对象URLConnection conn = url.openConnection();//然后可以通过URLConnection获取到一个输入流InputStream is = conn.getInputStream();//建立一个输出流用来写文件OutputStream os = new FileOutputStream("c:/infoq.txt");//现在开始就是I/O编程了byte[] buffer = new byte[2048];int length = 0;while(-1 != (length = is.read(buffer, 0, buffer.length))){os.write(buffer, 0, length);}is.close();os.close();}}

编译执行结果,在C盘根目录生成infoq.txt文件,打开显示如下,它是一个html文件

【说明】:上述通过URL获得输入流是第一种方式,现在有一种更简单的方式,通过URL类里面的openStream()方法,也就是可以直接通过URL这个类打开输入流。


URL url = new URL("http://infoq.com");/*//打开连接,获取到远程URL进行连接的URL对象URLConnection conn = url.openConnection();//然后可以通过URLConnection获取到一个输入流InputStream is = conn.getInputStream();*///这行代码等价于上述两行代码的实现InputStream is = url.openStream();//建立一个输出流用来写文件 OutputStream os = new FileOutputStream("c:/infoq.txt");//现在开始就是I/O编程了byte[] buffer = new byte[2048];int length = 0;while(-1 != (length = is.read(buffer, 0, buffer.length))){os.write(buffer, 0, length);}is.close();os.close();

【说明】:这种方式与上面的效果是一样的,只不过它提供了一种比较简单的方式而已的

查看openStream()的源代码如下所示,可以发现它也是基于openConnection()来的。

    public final InputStream openStream() throws java.io.IOException {        return openConnection().getInputStream();    }






原创粉丝点击