资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第,14,章,Java,网络编程,14.1 URL,类,URL,类是,包中的一个重要的类,,URL,的实例封装着一个统一资源定位符(,Uniform Resource Locator,),使用,URL,创建对象的应用程序称作客户端程序。一个,URL,对象封装着着一个具体的资源的引用,表明客户要访问这个,URL,中的资源,客户利用,URL,对象可以获取,URL,中的资源。一个,URL,对象通常包含最基本的三部分信息:协议、地址、资源。协议必须是,URL,对象所在的,Java,虚拟机支持的协议,许多协议并不为我们所常用,而常用的,Http,、,Ftp,、,File,协议都是虚拟机支持的协议;地址必须是能连接的有效,IP,地址或域名;资源可以是主机上的任何一个文件,14.1.1 URL,的构造方法,URL,类通常使用如下的构造方法创建一个,URL,对象:,public,URL(String,spec)throws,MalformedURLException,该构造方法使用字符串初始化一个,URL,对象,另一个常用的构造方法是:,public,URL(String,protocol,String,host,String,file)throws,MalformedURLException,该构造方法构造使用的协议、地址和资源分别由参数,protocol,、,host,和,file,指定,14.1.2,读取,URL,中的资源,URL,对象调用,InputStream,openStream,(),方法可以返回一个输入流,该输入流指向,URL,对象所包含的资源。通过该输入流可以将服务器上的资源信息读入到客户端。,URL,对象调用,InputStream,openStream,(),方法可以返回一个输入流,该输入流指向,URL,对象所包含的资源。通过该输入流可以将服务器上的资源读入到客户端,14.2,InetAdress,类,14.2.1,地址的表示,Internet,上的主机有两种方式表示地址:,1,域名,例如,,2,IP,地址,例如,,202.108.35.210,包中的,InetAddress,类对象含有一个,Internet,主机地址的域名和,IP,地址:, String,getHostName,(),获取,InetAddress,对象所含的域名。,public String,getHostAddress,(),获取,InetAddress,对象所含的,IP,地址。,2,获取本地机的地址,我们可以使用,InetAddress,类的静态方法:,getLocalHost,(),获得一个,InetAddress,对象,该对象含有本地机的域名和,IP,地址。,14.3,套接字,14.3.1,套接字,网络通信使用,IP,地址标识,Internet,上的计算机,使用端口号标识服务器上的进程(程序)。也就是说,如果服务器上的一个程序不占用一个端口号,用户程序就无法找到它,就无法和该程序交互信息。端口号被规定为一个,16,位的,065535,之间的整数,其中,,01023,被预先定义的服务通信占用(如,telnet,占用端口,23,,,http,占用端口,80,等),除非我们需要访问这些特定服务,否则,就应该使用,102465535,这些端口中的某一个进行通信,以免发生端口冲突,当两个程序需要通信时,它们可以通过使用,Socket,类建立套接字对象并连接在一起,14.3.2,客户端套接字,客户端的程序使用,Socket,类建立负责连接到服务器的套接字对象。,Socket,的构造方法是:,Socket(String,host,int,port),,参数,host,是服务器的,IP,地址,,port,是一个端口号。建立套接字对象可能发生,IOException,异常,因此应象下面那样建立连接到服务器的套接字对象:,try Socket,mysocket,=new Socket(http:/192.168.0.78,2010);,catch(IOException,e),14.3.3,ServerSocket,对象与服务器端套接字,为了能使客户成功地连接到服务器,服务器必须建立一个,ServerSocket,对象,该对象通过将客户端的套接字对象和服务器端的一个套接字对象连接起来,从而达到连接的目的。,ServerSocket,的构造方法是:,ServerSocket(int,port),,,port,是一个端口号。,port,必须和客户呼叫的端口号相同。当建立,ServerSocket,对象时可能发生,IOException,异常,因此应象下面那样建立,ServerSocket,对象:,try,ServerSocket,serverForClient,=new ServerSocket(2010);,catch(IOException,e),当服务器的,ServerSocket,对象,serverForClient,建立后,就可以使用方法,accept(),将客户的套接字和服务器端的套接字连接起来,代码如下所示:,try Socket sc=,serverForClient.accept,();,catch(IOException,e),客户端的,Socket,输入流,输出流,服务器端,Socket,输出流,输入流,图,14.2,套接字连接示意图,互相连接,互相连接,连接建立后,服务器端的套接字对象调用,getInetAddress,(),方法可以获取一个,InetAddess,对象,该对象含有客户端的,IP,地址和域名,同样,客户端的套接字对象调用,getInetAddress,(),方法可以获取一个,InetAddess,对象,该对象含有服务器端的,IP,地址和域名。,双方通信完毕后,套接字应使用,close(),方法关闭套接字连接,14.3.4,使用多线程技术,从套接字连接中读取数据与从文件中读取数据有着很大的不同。尽管二者都是输入流,但从文件中读取数据时,所有的数据都已经在文件中了,而使用套接字连接时,可能在另一端数据发送出来之前,就已经开始试着读取了,这时,就会堵塞本线程,直到该读取方法成功读取到信息,本线程才继续执行后续的操作。因此,服务器端收到一个客户的套接字后,就应该启动一个专门为该客户服务的线程,服务器程序,客户,1,的线程,客户,1,客户,2,的线程,客户,2,客户,3,的线程,客户,3,图,14.5,具有多线程的服务器端程序,可以使用,Socket,类的不带参数的构造方法,Socket(),创建一个套接字对象,该对象再调用,public void,connect(SocketAddress,endpoint)throws,IOException,请求和参数,SocketAddress,指定地址的服务器端的套接字建立连接。为了使用,connect,方法,可以使用,SocketAddress,的子类:,InetSocketAddress,创建一个对象,,InetSocketAddress,的构造方法是:,public,InetSocketAddress(InetAddress,addr,int,port),14.4 UDP,数据报,基于,UDP,的通信和基于,TCP,的通信不同,基于,UDP,的信息传递更快,但不提供可靠性保证。也就是说,数据在传输时,用户无法知道数据能否正确到达目的地主机,也不能确定数据到达目的地的顺序是否和发送的顺序相同。可以把,UDP,通信比作生活中的邮递信件,我们不能肯定所发的信件就一定能够到达目的地,也不能肯定到达的顺序是发出时的顺序,可能因为某种原因导致后发出的先到达。,基于,UDP,通信的基本模式是:,将数据打包,称为数据包(好比将信件装入信封一样),然后将数据包发往目的地。,接受别人发来的数据包(好比接收信封一样),然后查看数据包中的内容。,14.4.1,发送数据包,1,用,DatagramPacket,类将数据打包,即用,DatagramPacket,类创建一个对象,称为数据包。用,DatagramPacket,的以下两个构造方法创建待发送的数据包:,DatagramPacket(byte,data,int,length,InetAddtress,address,int,port),:,使用该构造方法创建的数据包对象具有下列两个性质:,含有,data,数组指定的数据。,该数据包将发送到地址是,address,、端口号是,port,的主机上。,我们称,address,是它的目标地址、,port,是这个数据包的目标端口。,DatagramPack(byte,data,int,offset,int,length,InetAddtress,address,int,port),使用该构造方法创建的数据包对象含有数组,data,中从,offset,开始后的,length,个字节,该数据包将发送到地址是,address,,端口号是,port,的主机上。,2,用,DatagramSocket,类的不带参数的构造方法:,DatagramSocket,(),创建一个对象,该对象负责发送数据包。例如:,DatagramSocket,mail_out,=new,DatagramSocket,();,mail_out.send(data_pack,);,14.4.2,接收数据包,首先用,DatagramSocket,的另一个构造方法:,DatagramSocket(int,port),创建一个对象,其中的参数必须和待接收的数据包的端口号相同。例如,如果发送方发送的数据包的端口是,5666,,那么如下创建,DatagramSocket,对象:,DatagramSocket,mail_in,=new DatagramSocket(5666);,然后对象,mail_in,使用方法,receive(DatagramPacket,pack),接受数据包。该方法有一个数据包参数,pack,,方法,receive,把收到的数据包传递给该参数。因此我们必须预备一个数据包以便收取数据包。这时需使用,DatagramPack,类的另外一个构造方法:,DatagramPack(byte,data,int,length),创建一个数据包,用于接收数据包,例如:,byte data=new byte100;,int,length=90;,DatagramPacket,pack=new,DatagramPacket(data,length,);,mail_in.receive(pack,);,该数据包,pack,将接收长度是,length,字节的数据放入,data,。,14.5,广播数据报,计算机使用,IP,地址和端口来区分其位置和进程,但有一类地址非常特殊,称作,D,类地址,,D,类地址不是用来代表位置的,即在网络上不能使用,D,类地址去查找计算机。,D,类地址好像生活中的社团组织,不同地理位置的人可以加入相同的组织,继而可以享有组织内部的通信权利。,Internet,的地址是,a.b.c.d,的形式。该地址的一部分代表用户自己的主机,而另一部分代表用户所在的网络。当,a,小于,128,,那么,b.c.d,就用来表示主机,这类地址称做,A,类地址。如果,a,大于等于,128,并且小于,192,,则,a.b,表示网络地址,而,c.d,表示主机地址,这类地址称做,B,类地址。如果,a,大于等于,192,,则网络地址是,a.b.c,,,d,表示主机地址,这类地址称做,C,类地址。,224.0.0.0224.255.255.255,是保留地址,称作,D,类地址,要广播或接收广播的主机都必须加入到同一个,D,类地址。一个,D,类地址也称做一个组播地址,,D,类地址并不代表某个特定主机的位置,一个具有,A,、,B,或,C,类地址的主机要广播数据或接收广播,
展开阅读全文