您的位置:首页 > 理论基础 > 计算机网络

java网络编程基础知识

2011-11-07 19:20 666 查看
 

一、网络基本概念

1、计算机网络,就是把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。

2、网络体系结构:国际标准化组织ISO于l978年提出“开放系统互连参考模型”,即著名的OSI(Open System Interconnection)模型。该模型把计算机网络分成物理层、数据链路层、网络层、传输层、会话层、表示层、应用层等七层。

 3、通信协议:计算机网络中实现通信必须有一些约定,即通信协议。对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。 

TCP协议:提供可靠的数据传输服务;(传输层)

IP协议进行IP数据包的分割和组装。(应用层)

二、IP地址和端口号

1、IP地址:为实现网络中不同的计算机之间的通信,在网络中的每台机器都必须有一个与众不同事标识,这就是IP地址(IP Address)。

格式:数字型、32位、由4段8位的二进制数组成。一般表示为十进制形式(4个0~255的十进制整数),中间用圆点隔开。如:166.111.78.98

域名地址:也是分段表示的,便于记忆的、字符串形式。

2、端口:一个16位的整数,用于表示数据交给哪个通信程序处理。因此,端口就是应用程序与外界交流的出入口,它是一种抽象的软件结构,包括一些数据结构和I/O(基本输入/输出)缓冲区。

不同的应用程序处理不同端口上的数据,同一台机器上不能有两个程序使用同一个端口,端口号可以从0到65535,通常将它分为三类:

*、公认端口(Well Known Ports):从0到1023,它们紧密绑定(Binding)一些服务。

*、注册端口(Registered Ports):从1024到49151。它们松散地绑定一些服务。

*、动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535,这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。

三、两类传输协议:TCP;UDP

尽管TCP/IP协议的名称中只有TCP这个协议名,但是在TCP/IP的传输层同时存在TCP和UDP两个协议。

   1、TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个 socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。

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

比较:

UDP:

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

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

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

TCP:

1, 面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接时间。

2, TCP传输数据大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的数据。

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

应用:

1,TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。

2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

补充:UDP协议的几个特性

(1) UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当 

  

UDP

它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。 

  (2) 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。 

  (3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。 

  (4) 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。 

(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。 

(6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。例如,在屏幕上报告股票市场、在屏幕上显示航空信息等等。UDP也用在路由信息协议RIP(Routing Information Protocol)中修改路由表。在这些应用场合下,如果有一个消息丢失,在几秒之后另一个新的消息就会替换它。UDP广泛用在多媒体应用中,例如,Progressive Networks公司开发的RealAudio软件,它是在因特
4000
网上把预先录制的或者现场音乐实时传送给客户机的一种软件,该软件使用的RealAudio audio-on-demand protocol协议就是运行在UDP之上的协议,大多数因特网电话软件产品也都运行在UDP之上

四、在Java中操纵UDP

使用位于JDK中Java.net包下的DatagramSocket和DatagramPacket类,可以非常方便地控制用户数据报文。

DatagramSocket类:创建接收和发送UDP的Socket实例

DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。 

DatagramSocket(int port):创建实例,并固定监听Port端口的报文。 

DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有 多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。 

receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。 

send(DatagramPacket d):发送报文d到目的地。 

setSoTimeout(int timeout):设置超时时间,单位为毫秒。 

close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。

DatagramPacket:用于处理报文,将byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成byte数组。 

DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从buf数组中,取出length长的数据创建数据包对象,目标是addr地址,port端口。 

DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从buf数组中,取出offset开始的、length长的数据创建数据包对象,目标是addr地址,port端口。 

DatagramPacket(byte[] buf, int offset, int length):将数据包中从offset开始、length长的数据装进buf数组。

DatagramPacket(byte[] buf, int length):将数据包中length长的数据装进buf数组。 

getData():它从实例中取得报文的byte数组编码。 

五、Socket的java网络编程

(1)基于Socket的java网络编程

1,什么是Socket

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

SOCKET(套接字/管套/插口):标识连接的端点,IP地址 + 端口号 。

应用程序与网络之间的接口 

       应用程序创建socket

       socket 类型 决定了通信的类型

       可靠的 vs. 尽最大努力的

        面向连接的 vs. 无连接的

一旦socket配置完成,应用程序就可以

          把数据传给socket,从而进行网络传输

         从socket接收数据(其他主机通过网络发送过来的)

2,Socket通讯的过程

Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。

对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1) 创建Socket;

  (2) 打开连接到Socket的输入/出流;

  (3) 按照一定的协议对Socket进行读/写操作;

  (4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)

3,创建Socket

创建Socket

ServerSocket:编写TCP网络服务程序,首先要用到java.net.ServerSocket类用以创建服务器Socket

构造方法:

ServerSocket(int port):创建绑定到特定端口的服务器套接字

ServerSocket(int port, int backlog):利用指定的backlog(服务器忙时保持连接请求的等待客户数量),创建服务器套接字并将其绑定到指定的本地端口号。

ServerSocket(int port, int backlog, InetAddress bindAddr):使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。

Socket:客户端要与服务器建立连接,必须先创建一个Socket对象

常用构造方法

Socket(String host, int port):创建一个流套接字并将其连接到指定主机上的指定端口号。

Socket(InetAddress address, int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:

  Socket(InetAddress address, int port);

  Socket(InetAddress address, int port, boolean stream);

  Socket(String host, int prot);

  Socket(String host, int prot, boolean stream);

  Socket(SocketImpl impl)

  Socket(String host, int port, InetAddress localAddr, int localPort)

  Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

  ServerSocket(int port);

  ServerSocket(int port, int backlog);

  ServerSocket(int port, int backlog, InetAddress bindAddr)

  其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可 以用来创建Socket。count则表示服务端所能支持的最大连接数。例如:

  Socket client = new Socket("127.0.01.", 80);

  ServerSocket server = new ServerSocket(80);

  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。

  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。

4,简单的Client/Server程序

1. 客户端程序

  import java.io.*;

  import java.net.*;

  public class TalkClient {

    public static void main(String args[]) {

      try{

        Socket socket=new Socket("127.0.0.1",4700);

        //向本机的4700端口发出客户请求

        BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));

        //由系统标准输入设备构造BufferedReader对象

        PrintWriter os=new PrintWriter(socket.getOutputStream());

        //由Socket对象得到输出流,并构造PrintWriter对象

        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

        //由Socket对象得到输入流,并构造相应的BufferedReader对象

        String readline;

        readline=sin.readLine(); //从系统标准输入读入一字符串

        while(!readline.equals("bye")){

        //若从标准输入读入的字符串为 "bye"则停止循环

          os.println(readline);

          //将从系统标准输入读入的字符串输出到Server

          os.flush();

          //刷新输出流,使Server马上收到该字符串

          System.out.println("Client:"+readline);

          //在系统标准输出上打印读入的字符串

          System.out.println("Server:"+is.readLine());

          //从Server读入一字符串,并打印到标准输出上

          readline=sin.readLine(); //从系统标准输入读入一字符串

        } //继续循环

        os.close(); //关闭Socket输出流

        is.close(); //关闭Socket输入流

        socket.close(); //关闭Socket

      }catch(Exception e) {

        System.out.println("Error"+e); //出错,则打印出错信息

      }

  }

}

 2. 服务器端程序

  import java.io.*;

  import java.net.*;

  import java.applet.Applet;

  public class TalkServer{

    public static void main(String args[]) {

      try{

        ServerSocket server=null;

        try{

          server=new ServerSocket(4700);

        //创建一个ServerSocket在端口4700监听客户请求

        }catch(Exception e) {

          System.out.println("can not listen to:"+e);

        //出错,打印出错信息

        }

        Socket socket=null;

        try{

          socket=server.accept();

          //使用accept()阻塞等待客户请求,有客户

          //请求到来则产生一个Socket对象,并继续执行

        }catch(Exception e) {

          System.out.println("Error."+e);

          //出错,打印出错信息

        }

        String line;

        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

         //由Socket对象得到输入流,并构造相应的BufferedReader对象

        PrintWriter os=newPrintWriter(socket.getOutputStream());

         //由Socket对象得到输出流,并构造PrintWriter对象

        BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));

         //由系统标准输入设备构造BufferedReader对象

        System.out.println("Client:"+is.readLine());

        //在标准输出上打印从客户端读入的字符串

        line=sin.readLine();

        //从标准输入读入一字符串

        while(!line.equals("bye")){

        //如果该字符串为 "bye",则停止循环

          os.println(line);

          //向客户端输出该字符串

          os.flush();

          //刷新输出流,使Client马上收到该字符串

          System.out.println("Server:"+line);

          //在系统标准输出上打印读入的字符串

          System.out.println("Client:"+is.readLine());

          //从Client读入一字符串,并打印到标准输出上

          line=sin.readLine();

          //从系统标准输入读入一字符串

        }  //继续循环

        os.close(); //关闭Socket输出流

        is.close(); //关闭Socket输入流

        socket.close(); //关闭Socket

        server.close(); //关闭ServerSocket

      }catch(Exception e){

        System.out.println("Error:"+e);

        //出错,打印出错信息

      }

    }

  }

3、支持多客户的client/server程序

前面的Client/Server程序只能实现Server和一个客户的对话。在实际应用 中,往往是在服务器上运行一个永久的程序,它可以接收来自其他多个客户端的请求,提供相应的服务。为了实现在服务器方给多个客户提供服务的功能,需要对上 面的程序进行改造,利用多线程实现多客户机制。服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响 应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。

ServerSocket serverSocket=null;

    boolean listening=true;

    try{

      serverSocket=new ServerSocket(4700);

      //创建一个ServerSocket在端口4700监听客户请求

    }catch(IOException e) {  }

    while(listening){ //永远循环监听

      new ServerThread(serverSocket.accept(),clientnum).start();

      //监听到客户请求,根据得到的Socket对象和

       客户计数创建服务线程,并启动之

      clientnum++; //增加客户计数

    }

    serverSocket.close(); //关闭ServerSocket

设计ServerThread类

 public class ServerThread extends Thread{

   Socket socket=null; //保存与本线程相关的Socket对象

   int clientnum; //保存本进程的客户计数

   public ServerThread(Socket socket,int num) { //构造函数

    this.socket=socket; //初始化socket变量

    clientnum=num+1; //初始化clientnum变量

   }

   public void run() { //线程主体

    try{//在这里实现数据的接受和发送}

 4、   DatagramSocket 类 

       要收发DatagramPacket必须打开一个数据报socket ,当服务器构造DatagramSocket时。

1.1 服务器和客户端的服务器 

      两者使用的socket都是一样的,区别仅仅在于 服务器端的端口是已知端口,而客户端的端口是系统分配的。

     TCP端口和UDP端口之间没有关联,所以两者可以共同绑定在同一个端口上,而不会有相互影响。

5、 DatagramSocket 类的构造函数   

      DatagramSocket创建一个在指定端口监听的入站数据报的 socket  ,使用此构造函数可以编写出在指导的端口监听的服务器。
      如果服务器在匿名端口监听,客户端就无法与之联系。

     DatagramSocket 中的receive 方法,是阻塞方法,只有当接收到数据的时候,才会进行下面的代码,否则只会阻塞当前的进程。

利用UDP协议来收发数据,都是将数据放在DatagramPacket 中,而TCP协议都是放在流中,通过getInputStream 和 getOutputStream 函数来获得流。

       在服务器端UDP需要调用含有端口参数的DatagramSocket 构造函数 , 在客户端设置DatagramSocket时,调用匿名端口构造函数。

       然后在构造DatagramPacket 构造函数的时候,发送端需要制定发送主机的 主机名 和 端口 。

基于URL的高层次Java网络编程 

 8.2.1一致资源定位器URL 

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

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

 

8.2.2 URL的组成 

  protocol://resourceName

  协议名(protocol)指明获取资源所使用的传输协议,如http、ftp、gopher、file等,资源名(resourceName)则应该是资源的完整地址,包括主机名、端口号、文件名或文件内部的一个引用。例如:

   http://www.sun.com/  协议名://主机名

   http://home.netscape.com/home/welcome.html  协议名://机器名+文件名

   http://www.gamelan.com:80/Gamelan/network.html#BOTTOM  协议名://机器名+端口号+文件名+内部引用

  端口号是和Socket编程相关的一个概念,初学者不必在此深究,在后面会有详细讲解。内部引用是HTML中的标记,有兴趣的读者可以参考有关HTML的书籍。 

8.2.3 创建一个URL

  为了表示URL, java.net中实现了类URL。我们可以通过下面的构造方法来初始化一个URL对象:

  (1) public URL (String spec);

     通过一个表示URL地址的字符串可以构造一个URL对象。

     URL urlBase=new URL(" http://www . 263.net/") 

  (2) public URL(URL context, String spec);

     通过基URL和相对URL构造一个URL对象。

     URL net263=new URL (" http://www.263.net/ ");

     URL index263=new URL(net263, "index.html") 

  (3) public URL(String protocol, String host, String file);

     new URL("http", " www.gamelan.com ", "/pages/Gamelan.net. html"); 

  (4) public URL(String protocol, String host, int port, String file);

     URL gamelan=new URL("http", " www.gamelan.com ", 80, "Pages/Gamelan.network.html"); 

  注意:类URL的构造方法都声明抛弃非运行时例外(MalformedURLException),因此生成URL对象时,我们必须要对这一例外进行处理,通常是用try-catch语句进行捕获。格式如下: 

  try{

     URL myURL= new URL(…)

  }catch (MalformedURLException e){

  …

  //exception handler code here

  …

  } 

8.2.4 解析一个URL

  一个URL对象生成后,其属性是不能被改变的,但是我们可以通过类URL所提供的方法来获取这些属性:

   public String getProtocol() 获取该URL的协议名。

   public String getHost() 获取该URL的主机名。

   public int getPort() 获取该URL的端口号,如果没有设置端口,返回-1。

   public String getFile() 获取该URL的文件名。

   public String getRef() 获取该URL在文件中的相对位置。

   public String getQuery() 获取该URL的查询信息。

   public String getPath() 获取该URL的路径

   public String getAuthority() 获取该URL的权限信息

   public String getUserInfo() 获得使用者的信息

   public String getRef() 获得该URL的锚 

  下面的例子中,我们生成一个URL 对象,并获取它的各个属性。 

  import java.net.*;

  import java.io.*; 

  public class ParseURL{

  public static void main (String [] args) throws Exception{ 

  URL Aurl=new URL(" http://java.sun.com:80/docs/books/ ");

  URL tuto=new URL(Aurl,"tutorial.intro.html#DOWNLOADING"); 

   System.out.println("protocol="+ tuto.getProtocol());

   System.out.println("host ="+ tuto.getHost());

   System.out.println("filename="+ tuto.getFile());

   System.out.println("port="+ tuto.getPort());

   System.out.println("ref="+tuto.getRef());

   System.out.println("query="+tuto.getQuery());

   System.out.println("path="+tuto.getPath());

   System.out.println("UserInfo="+tuto.getUserInfo());

   System.out.println("Authority="+tuto.getAuthority());

  }

  } 

  执行结果为:

    protocol=http host =java.sun.com filename=/docs/books/tutorial.intro.html 

   port=80 

    ref=DOWNLOADING 

   query=null 

    path=/docs/books/tutorial.intro.html 

   UserInfo=null 

    Authority=java.sun.com:80 

 

8.2.5 从URL读取WWW网络资源 

  当我们得到一个URL对象后,就可以通过它读取指定的WWW资源。这时我们将使用URL的方法openStream(),其定义为:

         InputStream openStream();

  方法openSteam()与指定的URL建立连接并返回InputStream类的对象以从这一连接中读取数据。

  public class URLReader {

  public static void main(String[] args) throws Exception { 

                      //声明抛出所有例外

    URL tirc = new URL(" http://www.tirc1.cs.tsinghua.edu.cn/ "); 

                      //构建一URL对象

    BufferedReader in = new BufferedReader(new InputStreamReader(tirc.openStream()));

    //使用openStream得到一输入流并由此构造一个BufferedReader对象

    String inputLine;

    while ((inputLine = in.readLine()) != null) 

                 //从输入流不断的读数据,直到读完为止

       System.out.println(inputLine); //把读入的数据打印到屏幕上

    in.close(); //关闭输入流

  }

  } 

 8.2.6 通过URLConnetction连接WWW 

  通过URL的方法 openStream(),我们只能从网络上读取数据,如果我们同时还想输出数据,例如向服务器端的CGI程序发送一些数据,我们必须先与URL建立连接,然后才能对其进行读写,这时就要用到类URLConnection了。CGI是公共网关接口(Common Gateway Interface)的简称,它是用户浏览器和服务器端的应用程序进行连接的接口,有关CGI程序设计,请读者参考有关书籍。 

  类URLConnection也在包 java.net中定义,它表示Java程序和URL在网络上的通信连接。当与一个URL建立连接时,首先要在一个URL对象上通过方法 openConnection()生成对应的URLConnection对象。例如下面的程序段首先生成一个指向地址 http://edu.chinaren.com/index.shtml 的对象,然后用openConnection()打开该URL对象上的一个连接,返回一个URLConnection对象。如果连接过程失败,将产生IOException. 

  Try{

    URL netchinaren = new URL (" http://edu.chinaren.com/index.shtml ");

    URLConnectonn tc = netchinaren.openConnection();

  }catch(MalformedURLException e){ //创建URL()对象失败

  …

  }catch (IOException e){ //openConnection()失败

  …

  } 

  类URLConnection提供了很多方法来设置或获取连接参数,程序设计时最常使用的是getInputStream()和getOurputStream(),其定义为:

      InputSteram getInputSteram();

     OutputSteram getOutputStream(); 

  通过返回的输入/输出流我们可以与远程对象进行通信。看下面的例子:

  URL url =new URL (" http://www.javasoft.com/cgi-bin/backwards "); 

  //创建一URL对象

  URLConnectin con=url.openConnection(); 

  //由URL对象获取URLConnection对象

   DataInputStream dis=new DataInputStream (con.getInputSteam()); 

  //由 URLConnection获取输入流,并构造DataInputStream对象

  PrintStream ps=new PrintSteam(con.getOutupSteam());

  //由URLConnection获取输出流,并构造 PrintStream对象

  String line=dis.readLine(); //从服务器读入一行

   ps.println("client…"); //向服务器写出字符串 "client…"

  其中backwards为服务器端的CGI程序。实际上,类URL的方法openSteam()是通过URLConnection来实现的。它等价于

     openConnection().getInputStream();

  基于URL的网络编程在底层其实还是基于下面要讲的 Socket接口的。WWW,FTP等标准化的网络服务都是基于TCP协议的,所以本质上讲URL编程也是基于TCP的一种应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息