Java网络编程

Java 网络编程

Java.net 包介绍:

 

InetAddress

这个 java.net.InetAddress 类是 Java IP 地址, IPv4 IPv6 的较高层次的标示,它是被其他的很多网络相关的类使用,包括 Socket,ServerSocket,URL,DatagramSocket,DatatgramSocket,DatagramPacket 等等。

通常情况下,它包含了一个主机名和 IP 地址。

public class InetAddress extends Object implements Serializable

注:在 Java1.3 和早期的版本中,这个类是 final 的,在 Java1.4 中,它有两个子类,但是,你不应该考虑这些子类,的确,你不能因为所有的构造方法都是包级别的保护权限。

那么怎么创造一个新的 InetAddress 对象呢?

没有公共的构造方法在 InetAddress 类里,然而, InetAddress 有三个静态的方法可以归还相应的初始化的 InetAddress 对象。它们是:

 

 

public static InetAddress getByName(String hostName)

 

  throws UnknownHostException

 

public static InetAddress[] getAllByName(String hostName)

 

  throws UnknownHostException

 

public static InetAddress getLocalHost( )

 

  throws UnknownHostException

 

 

假如必要,这三个方法都做了一个连接和局部的 DNS 服务器去,构造这个 InetAddress 对象的信息,这个可能有许多可能的没有预料到的异常,如果和 DNS 服务器的连接被禁止,这些方法可能会抛出安全异常。

 

Java1.4 引入了两个新的包, Inet4Address Inet6Address ,目的是为了区分 Ipv4 地址和 Ipv6 地址。

public final class Inet4Address

 extends InetAddress



public final class Inet6Address

 extends InetAddress



(

 Java1.3

和早期版本中,所有的InetAddress

对象都代表Ipv4

地址)



通常情况下,你确实不应该关注一个地址是IPv4

还是IPv6.

在应用了java

程序的应用层,你不需要知道(即使你的确需要知道,用getAddress()

方法,查看返回的字节数组的大小,而不是用instanceof

去测试它是哪一个子类)。大部分情况情况下着这两个类的实现细节,你不需要关心)。在Inet4Address

中覆盖了一些方法InetAddress

,但是它并没有改变在公共方法中的行为,它增加了一个新的父类中没有的方法,isIPv4CompatibleAddress();



Java.net.URL

这个类是统一资源定位定位符的像http://www.hamsterdance.com/ ftp://ftp.redhat.com/pub/ 的一种抽象描述标示,它继承了java.lang.Object, 是一个final 类不能被继承,它使用了策略设计模式,协议处理器是策略,这个类它本身形成内容通过选择不同的策略。

public final class URL extends Object implements Serializable

虽然存储一个 URL 类作为一个字符串是繁琐的,但是它是有意义的去考虑 URL 做为一个对象有 sheme(the protocol),hostname, port, path, quesry string fragment idertifier, 各个部分可以被设置独立的,的确,这几乎是最精确的,这个 java.net.URL 类是被组织,尽管这个细节是有微小的变化在不同版本的 Java 中,这个字段 java.net.URL 是仅仅可见的对于那些和 java.net.package 在同一个包中的成员,那些和 java.net 不是在同一个包中的类不能访问 java.net 中的成员变量直接地,然而,你可以设置这些字段通过 URL 构造函数和检索字段通过一些 get 方法 (getHost(), getPort() 等等 ) URL 对象是不可以变化的,一旦这个 URL 对象是被构件了,这些字段的值是不可以被改变的。

 

 

try {

 

  

URL u = new URL("http://www.audubon.org/");

 

}

 

catch (MalformedURLException ex)  

{

 

  

System.err.println(ex);

 

}

 

所得的构造函数都会抛出一个 MalformedURLException ,假如你用一个 java 虚拟机不支持的协议 (scheme) 去构造一个 URL 对象。或者这个 URL 是语法上不正确的。但不会做出一个检查对这个 URL 是有效的,或者说这个 URL 是存在的。

try {

 

  URL u = new URL("http", "fourier.dur.ac.uk", 8000, "/~dma3mjh/jsci/");

 

}

 

catch (MalformedURLException ex)  {

 

  System.err.println(ex);

 

}

 

This code creates a URL object that points to http://fourier.dur.ac.uk:8000/~dma3mjh/jsci/ , specifying port 8000 explicitly.

 

Constructing relative URLs

public URL(URL base, String relative) throws MalformedURLException

try {

 

  

URL u1 = new URL("http://www.ibiblio.org/javafaq/index.html");

 

  

URL u2 = new URL (u1, "mailinglists.html");

 

}

 

catch (MalformedURLException ex) {

 

   

System.err.println(ex);

 

}

 

URLs are composed of five pieces:

·         The scheme, also known as the protocol

·         The authority

·         The path

·         The fragment identifier, also known as the section or ref

·         The query string

 

The authority may further be divided into the user info, the host, and the port. For example, in the URL http://[email protected]:8080/ , the authority is [email protected]:8080 . This has the user info admin , the host www.blackstar.com , and the port 8080 .

 

 

try {

 

  

URL u  

= new URL("http://www.hamsterdance.com");

 

  

InputStream in = u.openStream( );

 

  

int c;

 

  

while ((c = in.read( )) != -1) System.out.write(c);

 

}

 

catch (IOException ex) {

 

  

System.err.println(ex);

 

}

 

java.url.URLConnection

URLConnection 鸡肋:

URLConnection does not have the best-designed API in the Java class library. Since the URLConnection class itself relies on the Socket class for network connectivity, there's little you can do with URLConnection that can't also be done with Socket . The URLConnection class is supposed to provide an easier-to-use, higher-level abstraction for network connections than Socket . In practice, however, most programmers have chosen to ignore it and simply use the Socket class. One of several problems is that the URLConnection class is too closely tied to the HTTP protocol. For instance, it assumes that each file transferred is preceded by a MIME header or something very much like one. However, most classic protocols such as FTP and SMTP don't use MIME headers. Another problem, one I hope to alleviate in this chapter, is that the URLConnection class is extremely poorly documented, so very few programmers understand how it's really supposed to work.

Opening URLConnection:

1.    Construct a URL object.

2.    Invoke the URL object's openConnection( ) method to retrieve a URLConnection object for that URL.

3.    Configure the URLConnection .

4.    Read the header fields.

5.    Get an input stream and read data.

6.    Get an output stream and write data.

7.    Close the connection.

 

URI 类:

URIURL 的一个抽象,它不仅仅代表包括统一资源定位器,而且包括统一资源名称空间,大部分在实际中被用的URIURL, 但是大部分的规范和标准像XML 是被定义用URI 术语,在Java1.4 和后续版本中,URI 对象是被描绘用java.net.URI 类,这个类不同于java.net.URL 在三个方面:                                   URI 类是纯粹的资源标示和分析URI 对象,它不提供任何方法去得到一个被URI 定义的资源的描述。

URI 类是比较一致的和相关的规范比URL 类。

一个URI 对象惨代表一个相当的URI, 但是这个URL 类绝对化所有的URI 对象在存储以前。

线程中一些方法的总结:

public static void yield()

Yielding 并不释放线程所占有的任何锁资源 ,因此,理想的情况,一个线程不应该是synchronized ,当它打算调用yield 方法时,它给其他的相同优先级的的线程 执行的机会,也就是说,如果另一个线程的优先级比较低,它有可能得不到这个机会。

public static void sleep(long milliseconds) throws InterruptedException

public static void sleep(long milliseconds, int nanoseconds) throws InterruptedException

Sleeping 是一个更有效的让出资源形式,鉴于yielding 指示那停止当前线程,让其它的有相等优先级的线程去运行,而sleep 将停止当前线程,它给其它的相同优先级的线程一个机会去运行,同时它也给低优先级的线程去运行的机会,相同点是,即使一个线程去睡眠,它也抱着那些它已经的锁资源,从而造成了,其它的那些需要这些锁资源的线程也不能运行,即使这个CPU 资源是空闲的。

对于现代的计算机时钟,对纳米精度是关闭的,纳米精度是少见的,因此没有能够确保你能实际上睡眠的精度在一个纳米的范围之内。

public void interrupt()

线程并不能确保去睡眠像它们要的时间,另一个线程能够唤醒一个正在睡眠的线程在它要求的睡眠时间到达以前,通常情况下,这个能够被完成,通过调用正在睡眠线程的interrupt() 方法。

在调用这个方法时,区别线程对象(Thread object) 和线程(Thread) 是重要的,仅仅因为这个线程是睡眠的,并不意味着其它的醒着线程的线程不能对这个共享的线程对象(Thread object) 的方法和变量进程操作。特殊情况下,另一个线程能够唤醒这个睡眠着的线程通过调用这个睡眠线程的interrupt() 方法。

Joining threads

public final void join() throws InterruptedException

public final void join(long  milliseconds) throws InterruptedException

public final void join(long milliseconds, int nanoseconds) throws InterruptedException

一个线程需要另一个线程的的结果是一个常见的情况,例如一个Web 浏览器用一个线程加载一个HTML 页面时,可能衍生一个独立的线程去获得这个页面上的每一张图片,假如一个IMG 元素没有高和宽的属性,这个主线程可能不得不等到所有的图像被加载,在它能完成显示这个页面。Java 提供了三个join() 方法,去准许一个线程等待另一个线程完成之后再继续执行。

第一个方法是在不确定的时间等待这个被joined 的线程去完成,第二个变体等待确定的时间,等到这个指定的时间是到了,即使这个被joined 的线程没有完成,它也将继续执行,正如这个sleep() 方法,纳米精度是不能保证的。

这个joining 线程( 也就是那个调用join() 方法的线程) 等待这个被joined 的线程( 也就是这一个谁的join() 方法被调用) 完成。

一个被joined 到另一个线程中的线程也能是被打断像一个sleeping 的线程,假如其它的线程调用了它的interrupt() 方法,这个线程将抛出一个InterruptedException. 从那个点以后,它正常的执行,开始从一个catch 语言块。

等待一个对象

一个线程能等待一个已经被锁定的对象。当等待时,它并不持有对象上的锁,它一直等待这个对象锁资源,直到它是被其它的一些线程通知,另一个线程用某种方式改变这个对象,通知在这个对象上等待的线程,然后继续。

public final void wait() throws InterruptedException

public final void  wait(long milliseconds) throws InterruptedException

public final void wait(long milliseconds, int nanoseconds) throws InterruptedException

这些方法不是在Thread 类里面。而是,它们是在java.lang.Object 类里面,因此,它们能是被调用被任何对象,当这些方法中的任意一个被调用,调用它的线程释放它正在等待的资源的锁,它是被唤醒当下面的情况发生时:

时间超时    线程是被打断     对象被唤醒

public final void notify( )

 

public final void notifyAll( )

UDPTCP

如果一个包丢失的话,TCP 要求一个重传或者等待不按时到达的包,在其它的应用程序中,可靠性的测试能是被执行在应用层,例如,假如一个客户端送一个短的UDP 请求到服务器,它可能认为这个包是丢失的,当没有响应是归还在一个设定的时间内,这是DNS 的工作方式,(DNS 也能是被操作通过TCP ),实际上,你能执行一个稳定的文件传输,通过UDP, 许多人认为:Network File System(NFS), Trivial FTP(TFTP)FSP, 一个相当较远的FTP, 都用UDP,( 这个最新版本的NFS 既能用UDP 也能用TCP.), 在这些协议里,应用层为可靠性做保证,UDP 不考虑它,也就是说,应用层必须处理丢失的,无序的包。

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Java网络编程)