java套接字编程.pdf
《java套接字编程.pdf》由会员分享,可在线阅读,更多相关《java套接字编程.pdf(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、JAVA 套接字编程 JAVA 套接字编程 用 Java 开发网络软件非常方便和强大,Java 的这种力量来源于他独有的一套强大的用于网络的 API,这些 API 是一系列的类和接口,均位于包 和 中。在这篇文章中我们将介绍套接字(Socket)慨念,同时以实例说明如何使用 Network API 操纵套接字,在完成本文后,你就可以编写网络低端通讯软件。什么是套接字什么是套接字(Socket)?Network API 是典型的用于基于 TCP/IP 网络 Java 程序与其他程序通讯,Network API 依靠 Socket 进行通讯。Socket 可以看成在两个程序进行通讯连接中的一个端点
2、,一个程序将一段信息写入 Socket 中,该 Socket 将这段信息发送给另外一个 Socket 中,使这段信息能传送到其他程序中。如图 1 我们来分析一下图 1,Host A 上的程序 A 将一段信息写入 Socket 中,Socket 的内容被 Host A 的网络管理软件访问,并将这段信息通过 Host A 的网络接口卡发送到 Host B,Host B 的网络接口卡接收到这段信息后,传送给 Host B 的网络管理软件,网络管理软件将这段信息保存在 Host B 的 Socket 中,然后程序 B 才能在 Socket 中阅读这段信息。假设在图 1 的网络中添加第三个主机 Host
3、 C,那么 Host A 怎么知道信息被正确传送到 Host B 而不是被传送到 Host C 中了呢?基于 TCP/IP 网络中的每一个主机均被赋予了一个唯一的 IP 地址,IP 地址是一个 32 位的无符号整数,由于没有转变成二进制,因此通常以小数点分隔,如:198.163.227.6,正如所见 IP 地址均由四个部分组成,每个部分的范围都是 0-255,以表示 8 位地址。值得注意的是 IP 地址都是 32 位地址,这是 IP 协议版本 4(简称 Ipv4)规定的,目前由于 IPv4 地址已近耗尽,所以 IPv6 地址正逐渐代替 Ipv4 地址,Ipv6 地址则是 128位无符号整数。假
4、设第二个程序被加入图 1 的网络的 Host B 中,那么由 Host A 传来的信息如何能被正确的传给程序 B 而不是传给新加入的程序呢?这是因为每一个基于 TCP/IP 网络通讯的程序都被赋予了唯一的端口和端口号,端口是一个信息缓冲区,用于保留 Socket中的输入/输出信息,端口号是一个 16 位无符号整数,范围是 0-65535,以区别主机上的每一个程序(端口号就像房屋中的房间号),低于 256 的短口号保留给标准应用程序,比如 pop3 的端口号就是 110,每一个套接字都组合进了 IP 地址、端口、端口号,这样形成的整体就可以区别每一个套接字 t,下面我们就来谈谈两种套接字:流套接
5、字和自寻址数据套接字。流套接字(流套接字(Stream Socket)无论何时,在两个网络应用程序之间发送和接收信息时都需要建立一个可靠的连接,流套接字依靠 TCP 协议来保证信息正确到达目的地,实际上,IP 包有可能在网络中丢失或者在传送过程中发生错误,任何一种情况发生,作为接受方的 TCP 将联系发送方 TCP 重新发送这个 IP 包。这就是所谓的在两个流套接字之间建立可靠的连接。流套接字在 C/S 程序中扮演一个必需的角色,客户机程序(需要访问某些服务的网络应用程序)创建一个扮演服务器程序的主机的 IP 地址和服务器程序(为客户端应用程序提供服务的网络应用程序)的端口号的流套接字对象。客
6、户端流套接字的初始化代码将 IP 地址和端口号传递给客户端主机的网络管理软件,管理软件将 IP 地址和端口号通过 NIC 传递给服务器端主机;服务器端主机读到经过 NIC 传递来的数据,然后查看服务器程序是否处于监听状态,这种监听依然是通过套接字和端口来进行的;如果服务器程序处于监听状态,那么服务器端网络管理软件就向客户机网络管理软件发出一个积极的响应信号,接收到响应信号后,客户端流套接字初始化代码就给客户程序建立一个端口号,并将这个端口号传递给服务器程序的套接字(服务器程序将使用这个端口号识别传来的信息是否是属于客户程序)同时完成流套接字的初始化。如果服务器程序没有处于监听状态,那么服务器端
7、网络管理软件将给客户端传递一个消极信号,收到这个消极信号后,客户程序的流套接字初始化代码将抛出一个异常对象并且不建立通讯连接,也不创建流套接字对象。这种情形就像打电话一样,当有人的时候通讯建立,否则电话将被挂起。这部分的工作包括了相关联的三个类:InetAddress,Socket,和 ServerSocket。InetAddress 对象描绘了32 位或 128 位IP 地址,Socket 对象代表了客户程序流套接字,ServerSocket 代表了服务程序流套接字,所有这三个类均位于包 中。InetAddress 类类 InetAddress 类在网络 API 套接字编程中扮演了一个重要角
8、色。参数传递给流套接字类和自寻址套接字类构造器或非构造器方法。InetAddress 描述了 32 位或 64 位 IP地址,要完成这个功能,InetAddress 类主要依靠两个支持类 Inet4Address 和 Inet6Address,这三个类是继承关系,InetAddrress 是父类,Inet4Address 和 Inet6Address 是子类。由于 InetAddress 类只有一个构造函数,而且不能传递参数,所以不能直接创建InetAddress 对象,比如下面的做法就是错误的:InetAddress ia=new InetAddress();但我们可以通过下面的 5 个工厂
9、方法创建来创建一个 InetAddress 对象或InetAddress 数组:.getAllByName(String host)方法返回一个 InetAddress 对象的引用,每个对象包含一个表示相应主机名的单独的 IP 地址,这个 IP 地址是通过 host 参数传递的,对于指定的主机如果没有 IP 地址存在那么这个方法将抛出一个 UnknownHostException 异常对象。.getByAddress(byte addr)方法返回一个 InetAddress 对象的引用,这个对象包含了一个 Ipv4 地址或 Ipv6 地址,Ipv4 地址是一个 4 字节数组,Ipv6 地址是一
10、个 16字节地址数组,如果返回的数组既不是 4 字节的也不是 16 字节的,那么方法将会抛出一个 UnknownHostException 异常对象。.getByAddress(String host,byte addr)方法返回一个InetAddress对象的引用,这个 InetAddress 对象包含了一个由 host 和 4 字节的 addr 数组指定的 IP 地址,或者是host 和 16 字节的 addr 数组指定的 IP 地址,如果这个数组既不是 4 字节的也不是 16位字节的,那么该方法将抛出一个 UnknownHostException 异常对象。.getByName(Stri
11、ng host)方法返回一个 InetAddress 对象,该对象包含了一个与host 参数指定的主机相对应的 IP 地址,对于指定的主机如果没有 IP 地址存在,那么方法将抛出一个 UnknownHostException 异常对象。.getLocalHost()方法返回一个 InetAddress 对象,这个对象包含了本地机的 IP地址,考虑到本地主机既是客户程序主机又是服务器程序主机,为避免混乱,我们将客户程序主机称为客户主机,将服务器程序主机称为服务器主机。上面讲到的方法均提到返回一个或多个 InetAddress 对象的引用,实际上每一个方法都要返回一个或多个 Inet4Addres
12、s/Inet6Address 对象的引用,调用者不需要知道引用的子类型,相反调用者可以使用返回的引用调用 InetAddress 对象的非静态方法,包括子类型的多态以确保重载方法被调用。InetAddress 和它的子类型对象处理主机名到主机 IPv4 或 IPv6 地址的转换,要完成这个转换需要使用域名系统,下面的代码示范了如何通过调用 getByName(String host)方法获得 InetAddress 子类对象的方法,这个对象包含了与 host 参数相对应的 IP地址:InetAddress ia=InetAddress.getByName();一但获得了 InetAddress
13、 子类对象的引用就可以调用 InetAddress 的各种方法来获得 InetAddress 子类对象中的 IP 地址信息,比如,可以通过调用getCanonicalHostName()从域名服务中获得标准的主机名;getHostAddress()获得 IP地址,getHostName()获得主机名,isLoopbackAddress()判断 IP 地址是否是一个loopback 地址。List1 是一段示范代码:InetAddressDemo/InetAddressDemo.java import .*;class InetAddressDemo public static void mai
14、n(String args)throws UnknownHostException String host=localhost;if(args.length=1)host=args 0;InetAddress ia=InetAddress.getByName(host);System.out.println(Canonical Host Name=+ia.getCanonicalHostName();System.out.println(Host Address=+ia.getHostAddress();System.out.println(Host Name=+ia.getHostName(
15、);System.out.println(Is Loopback Address=+ia.isLoopbackAddress();当无命令行参数时,代码输出类似下面的结果:Canonical Host Name=localhost Host Address=127.0.0.1 Host Name=localhost Is Loopback Address=true InetAddressDemo 给了你一个指定主机名作为命令行参数的选择,如果没有主机名被 指 定,那 么 将 使 用localhost(客 户 机 的),InetAddressDemo通 过 调 用getByName(String
16、 host)方法获得一个 InetAddress 子类对象的引用,通过这个引用获得了标准主机名,主机地址,主机名以及 IP 地址是否是 loopback 地址的输出。Socket 类类 当客户程序需要与服务器程序通讯的时候,客户程序在客户机创建一个 socket 对象,Socket 类有几个构造函数。两个常用的构造函数是 Socket(InetAddress addr,int port)和 Socket(String host,int port),两个构造函数都创建了一个基于 Socket 的连接服务器端流套接字的流套接字。对于第一个 InetAddress 子类对象通过 addr 参数获得服
17、务器主机的 IP 地址,对于第二个函数 host 参数包被分配到 InetAddress 对象中,如果没有 IP 地址与 host 参数相一致,那么将抛出 UnknownHostException 异常对象。两个函数都通过参数 port 获得服务器的端口号。假设已经建立连接了,网络 API 将在客户端基于 Socket 的流套接字中捆绑客户程序的 IP 地址和任意一个端口号,否则两个函数都会抛出一个 IOException 对象。如果创建了一个 Socket 对象,那么它可能通过调用 Socket 的 getInputStream()方法从服务程序获得输入流读传送来的信息,也可能通过调用 So
18、cket 的 getOutputStream()方法获得输出流来发送消息。在读写活动完成之后,客户程序调用close()方法关闭流和流套接字,下面的代码创建了一个服务程序主机地址为198.163.227.6,端口号为 13 的 Socket 对象,然后从这个新创建的 Socket 对象中读取输入流,然后再关闭流和 Socket 对象。Socket s=new Socket(198.163.227.6,13);InputStream is=s.getInputStream();/Read from the stream.is.close();s.close();接下面我们将示范一个流套接字的客户
19、程序,这个程序将创建一个 Socket 对象,Socket 将访问运行在指定主机端口 10000 上的服务程序,如果访问成功客户程序将给服务程序发送一系列命令并打印服务程序的响应。List2 使我们创建的程序 SSClient 的源代码:Listing 2:SSClient.java/SSClient.java import java.io.*;import .*;class SSClient public static void main(String args)String host=localhost;/If user specifies a command-line argument,
20、that argument /represents the host name.if(args.length=1)host=args 0;BufferedReader br=null;PrintWriter pw=null;Socket s=null;try /Create a socket that attempts to connect to the server /program on the host at port 10000.s=new Socket(host,10000);/Create an input stream reader that chains to the sock
21、ets /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.InputStreamReader isr;isr=new InputStreamReader(s.getInputStream();/Create a buffered reader that chains to the input stream /re
22、ader.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-/oriented output stream.The print writer creates an /intermediate output stream writer that converts /characters sent to the socke
23、t 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.println(DATE);/Obtain and print the current date/time.System.out.println(br.readLine();/Send the PAUSE command to the server.This allows sev
24、eral /clients to start and verifies that the server is spawning /multiple threads.pw.println(PAUSE);/Send the DOW command to the server.pw.println(DOW);/Obtain and print the current day of week.System.out.println(br.readLine();/Send the DOM command to the server.pw.println(DOM);/Obtain and print the
25、 current day of month.System.out.println(br.readLine();/Send the DOY command to the server.pw.println(DOY);/Obtain and print the current day of year.System.out.println(br.readLine();catch(IOException e)System.out.println(e.toString();finally try if(br!=null)br.close();if(pw!=null)pw.close();if(s!=nu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 套接 编程
限制150内