1、String host = localhost;if (args.length = 1)host = args 0;InetAddress ia = InetAddress.getByName (host);System.out.println (Canonical Host Name = +ia.getCanonicalHostName ();Host Address = ia.getHostAddress ();Host Name = ia.getHostName ();Is Loopback Address = ia.isLoopbackAddress ();当无命令行参数时,代码输出类
2、似下面的结果:Canonical Host Name = localhost Host Address = 127.0.0.1 Host Name = localhost Is Loopback Address = true InetAddressDemo给了你一个指定主机名作为命令行参数的选择,如果没有主机名被指定,那么将使用localhost(客户机的),InetAddressDemo通过调用getByName(String host)方法获得一个InetAddress子类对象的引用,通过这个引用获得了标准主机名,主机地址,主机名以及IP地址是否是loopback地址的输出。当客户程序需要
3、与服务器程序通讯的时候,客户程序在客户机创建一个socket对象,Socket类有几个构造函数。两个常用的构造函数是 Socket(InetAddress addr, int port) 和 Socket(String host, int port),两个构造函数都创建了一个基于Socket的连接服务器端流套接字的流套接字。对于第一个InetAddress子类对象通过addr参数获得服务器主机的IP地址,对于第二个函数host参数包被分配到InetAddress对象中,如果没有IP地址与host参数相一致,那么将抛出UnknownHostException异常对象。两个函数都通过参数port获
4、得服务器的端口号。假设已经建立连接了,网络API将在客户端基于Socket的流套接字中捆绑客户程序的IP地址和任意一个端口号,否则两个函数都会抛出一个IOException对象。如果创建了一个Socket对象,那么它可能通过调用Socket的 getInputStream()方法从服务程序获得输入流读传送来的信息,也可能通过调用Socket的 getOutputStream()方法获得输出流来发送消息。在读写活动完成之后,客户程序调用close()方法关闭流和流套接字,下面的代码创建了一个服务程序主机地址为198.163.227.6,端口号为13的Socket对象,然后从这个新创建的Socke
5、t对象中读取输入流,然后再关闭流和Socket对象。Socket s = new Socket (198.163.227.6, 13);InputStream is = s.getInputStream ();/ Read from the stream.is.close ();s.close ();接下面我们将示范一个流套接字的客户程序,这个程序将创建一个Socket对象,Socket将访问运行在指定主机端口10000上的服务程序,如果访问成功客户程序将给服务程序发送一系列命令并打印服务程序的响应。List2使我们创建的程序SSClient的源代码:Listing 2: SSClient.j
6、ava / SSClient.javaimport java.io.*;class SSClientpublic static void main (String args)/ If user specifies a command-line argument, that argument/ redivsents the host name.BufferedReader br = null;PrintWriter pw = null;Socket s = null;try/ Create a socket that attempts to connect to the server/ prog
7、ram on the host at port 10000.s = new Socket (host, 10000);/ Create an input stream reader that chains to the sockets/ byte-oriented input stream. The input stream reader/ converts bytes read from the socket to characters. The/ conversion is based on the platforms default character/ set.InputStreamR
8、eader isr;isr = new InputStreamReader (s.getInputStream ();/ Create a buffered reader that chains to the input stream/ reader. The buffered reader supplies a convenient method/ for reading entire lines of text.br = new BufferedReader (isr);/ Create a print writer that chains to the sockets byte-/ or
9、iented output stream. The print writer creates an/ intermediate output stream writer that converts/ characters sent to the socket to bytes. The conversion/ is based on the platforms default character set.pw = new PrintWriter (s.getOutputStream (), true);/ Send the DATE command to the server.pw.print
10、ln (DATE);/ Obtain and print the current date/time.System.out.println (br.readLine ();/ Send the PAUSE command to the server. This allows several/ clients to start and verifies that the server is spawning/ multiple threads.PAUSE/ Send the DOW command to the server.DOW/ Obtain and print the current d
11、ay of week./ Send the DOM command to the server.DOM/ Obtain and print the current day of month./ Send the DOY command to the server.DOY/ Obtain and print the current day of year.catch (IOException e)System.out.println (e.toString ();finallytryif (br != null)br.close ();if (pw !pw.close ();if (s !s.c
12、lose ();catch (IOException e)运行这段程序将会得到下面的结果:Tue Jan 29 18:11:51 CST 2002 TUESDAY 29 SSClient创建了一个Socket对象与运行在主机端口10000的服务程序联系,主机的IP地址由host变量确定。SSClient将获得Socket的输入输出流,围绕BufferedReader的输入流和PrintWriter的输出流对字符串进行读写操作就变得非常容易,SSClient个服务程序发出各种date/time命令并得到响应,每个响应均被打印,一旦最后一个响应被打印,将执行Try/Catch/Finally结构的
13、Finally子串,Finally子串将在关闭Socket之前关闭BufferedReader 和 PrintWriter。在SSClient源代码编译完成后,可以输入java SSClient 来执行这段程序,如果有合适的程序运行在不同的主机上,采用主机名/IP地址为参数的输入方式,比如是运行服务器程序的主机,那么输入方式就是java SSClient 。技巧 Socket类包含了许多有用的方法。比如getLocalAddress()将返回一个包含客户程序IP地址的InetAddress子类对象的引用;getLocalPort()将返回客户程序的端口号;getInetAddress()将返回
14、一个包含服务器IP地址的InetAddress子类对象的引用;getPort()将返回服务程序的端口号。Datagram(数据包)是一种尽力而为的传送数据的方式,它只是把数据的目的地记录在数据包中,然后就直接放在网络上,系统不保证数据是否能安全送到,或者什么时候可以送到,也就是说它并不保证传送质量。1 UDP套接字 数据报(Datagram)是网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址信息的消息,它能否到达目的地、到达的时间、到达时内容是否会变化不能准确地知道。它的通信双方是不需要建立连接的,对于一些不需要很高质量的应用程序来说,数据报通信是
15、一个非常好的选择。还有就是对实时性要求很高的情况,比如在实时音频和视频应用中,数据包的丢失和位置错乱是静态的,是可以被人们所忍受的,但是如果在数据包位置错乱或丢失时要求数据包重传,就是用户所不能忍受的,这时就可以利用UDP协议传输数据包。在Java的包中有两个类DatagramSocket和DatagramPacket,为应用程序中采用数据报通信方式进行网络通信。使用数据包方式首先将数据打包,Javanet包中的DategramPacket类用来创建数据包。数据包有两种,一种用来传递数据包,该数据包有要传递到的目的地址;另一种数据包用来接收传递过来的数据包中的数据。要创建接收的数据包,通过Da
16、tagramPackett类的方法构造:public DatagramPacket(byte ibuft,int ilength) public DatagramPacket( byte ibuft,int offset ,int ilength) ibuf为接受数据包的存储数据的缓冲区的长度,ilength为从传递过来的数据包中读取的字节数。当采用第一种构造方法时,接收到的数据从ibuft0开始存放,直到整个数据包接收完毕或者将ilength的字节写入ibuft为止。采用第二种构造方法时,接收到的数据从ibuftoffset开始存放。如果数据包长度超出了ilength,则触发IllegalA
17、rgument-Exception。不过这是RuntimeException,不需要用户代码捕获。示范代码如下:byte buffernew byte8912;DatagramPacket datap=new DatagramPacket(buffer ,buffer.length( );创建发送数据包的构造方法为:public DatagramPacket(byt ibuf,int ilength,InetAddrss iaddr,int port) public DatagramPacket(byt ibuf,int offset , int ilength,InetAddrss iadd
18、r,int port) iaddr为数据包要传递到的目标地址,port为目标地址的程序接受数据包的端口号(即目标地址的计算机上运行的客户程序是在哪一个端口接收服务器发送过来的数据包)。ibuf为要发送数据的存储区,以ibuf数组的offset位置开始填充数据包ilength字节,如果没有offset,则从ibuf数组的0位置开始填充。以下示范代码是要发送一串字符串:String s = new String(java networkingbyte data=s.getbytes();int port=1024;tryInetAddress ineta= InetAddress.getByNam
19、e( 169.254.0.14DatagramPacket datap=new DatagramPacket(data ,data.length( ),ineta,port);catch(IOException e) 数据包也是对象,也有操作方法用来获取数据包的信息,这是很有用的。其方法如下:public InetAddress getAddress() 如果是发送数据包,则获得数据包要发送的目标地址,但是如果是接收数据包则返回发送此数据包的源地址。public bytegetData() 返回一个字节数组,其中是数据包的数据。如果想把字节数组转换成别的类型就要进行转化。如果想转化成Strin
20、g类型,可以进行以下的处理,设DatagramPacket datap为:String s = new String(datap.getbytes();public int getLength() 获得数据包中数据的字节数。pubic int getPort( ) 返回数据包中的目标地址的主机端口号。发送和接收数据包还需要发送和接收数据包的套接字,即DatagramSocket对象,DatagramSocket套接字在本地机器端口监听是否有数据到达或者将数据包发送出去。其构造方法如下。public DatagramSocket() 用本地机上任何一个可用的端口创建一个套接字,这个端口号是由系统
21、随机产生的。使用方法如下:DatagramSocket datas=new DatagramSocket( );/发送数据包catch(SocketException e)这种构造方法没有指定端口号,可以用在客户端。如果构造不成功则触发SocketException异常。public DatagramSocket(int port) 用一个指定的端口号port创建一个套接字。当不能创建套接字时就抛出SocketException异常,其原因是指定的端口已被占用或者是试图连接低于1024的端口,但是又没有具备权限。2 实例:利用DatagramSocket查询端口占用情况 我们可以利用这个异常探
22、查本地机的端口号有没有服务。见示例12-9。【程序源代码】 1 / = Program Description =2 / 程序名称:示例12-9: UDPScan.java3 / 程序目的:熟悉DatagramSocket的基本用法,查询端口的占用情况4 /=5 import .*;6 7 public class UDPScan8 9 public static void main(String args)10 11 for (int port=1024;port=65535;port+) 12 try 13 DatagramSocket server=new DatagramSocket(port);14 server.close();15 16 catch(SocketException e) 17 System.out.println(there is a server in port +port+.18 19 20 21 【程序输出结果】 there is a server in port 1026. there is a server in port 1028. there is a server in port 1046. there
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1