您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > JAVA第11章-网络编程
新一代信息技术“十三五”系列规划教材刘刚刘伟编著第11章网络编程Java成功应用的一个重要领域就是网络。同Java的集合一样,Java在JDK中也加入了大量和网络相关的类,将多种Internet协议封装到在这些类中,这也让Java网络程序的编写更加容易。与网络相关的功能集中在java.net包中,开发者无需过深地了解相关的协议也能实现网络应用中各种C/S(客户机/服务机器)和B/S(浏览器/服务器)的通信程序。11.1网络通信协议构建网络的目的就是为了通信,但不同计算机之间的通信存在着很大的困难,为了克服这些困难,就需要构建统一的网络通信标准,即网络协议。网络协议就是计算机通信双方在通信时必须遵循的一组规范。Java的网络包简化了网络程序的开发,为了更好地使用这些包中的类,需要对网络开发中可能会涉及的名词诸如TCP/IP协议、UDP协议、域名、套接字、URL、端口等有初步的了解。11.1.1TCP及UDP协议TCP/IP协议(TransmissionControlProtocol/InternetProtocol)也叫做传输控制/网际协议,又叫做网络通信协议。TCP/IP协议是英特网中使用的基本通信协议,该协议包含有两个保证数据完整传输的重要协议:传输控制协议(TCP)和网际协议(IP),同时包含上百个各种其他功能的协议,通常说的TCP/IP协议是Internet协议族。UDP是UserDatagramProtocol的简称,全称是用户数据报协议,中文名是用户数据报协议,是OSI(OpenSystemInterconnection,开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。不同于TCP/IP的可靠信息传送,UDP协议无需三次握手确保连接双方都已准备就绪就可以传输数据,即使目标地址不可达,这种不可靠的数据传送服务在无需确保数据完整性和实时反馈的场景下使用,因为免去了三次握手,所以消耗的服务器负载要远小于TCP/IP。套接字(Socket)是TCP/IP中的基本概念,负责将TCP/IP包发送到指定的IP地址。可以看作是两个程序通信连接中的一个端点,一个用于将数据写入Socket中,该Socket将数据发送到另一个Socket中,使得该数据能够传送给其他程序。URL(UniformResourceLocator)统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。URL由Internet资源类型(http或ftp等)、服务器地址(host)、端口(port)和资源位于服务器上的位置组成。Java中有对应的URL类和URLConnection类。运行结果如图11-1所示。图11-1运行结果在实际的开发中,客户能设定请求头的键值对和获取响应头的键值对数据,这些操作都是通过URLConnetcion类来完成的,不过请求头信息的添加键值对操作必须在连接还未建立之前进行。11.1.2IP地址及端口号网络之间互连的协议(IP)是InternetProtocol的缩写,中文缩写为“网协”,是为计算机网络相互连接进行通信而设计的协议,任何厂家生产的计算机系统,只要遵守IP协议就可以与因特网互连互通。IP地址具有唯一性,用于唯一标识网络中的一台设备。由于现行网络设备过多导致IPv4(现行的IP版本)地址分配收紧,IETF小组设计了IPv6来解决网络设备过多的问题。IPv4使用4个字节的小于256的数组以“.”连接起来的32bit长度的串,如212.32.1.124,IPv6则使用8个16位的无符号整数用冒号“:”隔开表示,例如6dfe:3312:1123:12df:dfdd:123s:fed2:ss4e。Java网络包中提供了Inet4Address类和Inet6Address类对IPv4和IPv6的IP地址。由于IP地址是数字标识,难于记忆和书写,所以在IP的基础上又发展出一种符号化的地址方案来代替数字型的IP地址,每一个符号化的地址与特定的IP对应,因为符号化的内容有其对应的意义和内容,所以记忆和书写都非常方便,这些符号化的地址就是域名,例如人民邮电出版社的域名就是:。但域名不能直接被网络设备所识别,需要有域名服务器(DNS)对域名与IP作对应的转换。计算机“端口”在英文中是port的音译,硬件中端口也称接口,在软件中一般是指网络中面向连接服务和无连接服务的通信协议识别代码,是一种抽象的软件结构,包括一些数据结构和I/O缓冲区。在计算机通信时,需要指定端口传递信息,端口可以是0~65535之间的任意一个整数,1024以内的端口在一些系统中被保留给了系统服务使用,其他的端口供其他程序使用,每个服务都需要跟一个特定的端口关联在一起,通信时客户端和管理端都需要首先知道这个通信的端口号。运行结果如图11-2所示。图11-2运行结果11.2TCP通信在日常生活中大家都会打电话,打电话这个场景就是一个可靠的通信场景,这个场景下你说的每一句话都会被对方听到,如果听不清楚你还可以再说一遍,确保对方听到了你说的话。还有一种通信,例如文件共享,你给你的朋友发了一个文件,但是你只确定你发了文件,你无法确定对方有没有收到,以及收到的文件是否完整,这就是下一节会说的UDP通信,即不可靠通信。11.2.1Socket当两个程序想要通信的时候,可以使用Socket类建立套接字连接,呼叫的一方成为客户机,接收的一方成为服务器,服务器使用的套接字是ServerSocket。Socket套接字和ServerSocket套接字使用的IP和端口号必须相同,端口号在服务器端和客户机端必须一致才能通信。一个典型的客户机/服务器对话过程如下。(1)服务器开启监听,监听指定端口。(2)客户机对指定的端口发起请求。(3)服务器接收到请求,进行处理并返回客户机处理结果。(4)客户机接收结果,做出后续处理。当一次对话过程结束之后,一定要关闭套接字。在Java中,Socket的创建有两种方式,一种是非阻塞式创建(这种方式可以设置超时):Socketso=newSocket();SocketAddresssaddr=newInetSocketAddress(InetAddress.getByName(),80);so.connect(saddr,3000);另一种是阻塞式创建:Socketso=newSocket();或者Socketso=newSocket(InetAddress.getByName(),80);这两种Socket的创建方式会在创建的时候一直阻塞,直到有连接响应。具体使用哪种方式创建套接字,可按实际情况进行选择。11.2.2ServerSocketServerSocket是服务器端套接字,对指定的端口进行监听,当监听到请求之后,可以使用accept()方法接收客户端发来的消息,该方法是阻塞的,直到有连接进来,才会返回一个Socket对象,服务器可以使用该Socket与客户端进行通信。Java中Socket的通信模型如图11-3所示。图11-3Socket的通信模型运行结果如图11-4所示。图11-4运行结果因为Socket和ServerSocket类均实现了Closeable接口,所以此处使用try(){…}的方式进行创建,这种方式一方面消除了流在关闭时可能会因特殊情况无法正常关闭的缺陷,另一方面省去了手动close()的步骤,使得代码更加精简。通过案例可以看出,客户端和服务端实际上都是在使用Socket的套接字进行通信,服务器端使用ServerSocket套接字调用accept()方法阻塞的监听客户端的请求,并返回一个与之对应的Socket套接字来实现数据的交互。Socket套接字有getInputStream()方法用于获取Socket中的数据,和getOutputStream()方法用于将数据放进Socket供对方读取。11.3UDP通信同TCP通信不同的是UDP通信,UDP是一种面向无连接的协议,在通信时无需通信双方建立连接即可进行通信。就像QQ和微信,用户之间无需进行打电话一样的联通就可以进行通信,当然时效性与TCP通信就没法比较了,可能A向B发送了一条消息,数天后A才收到并回复,如果这条信息对时效性要求不强,那么这种方式比打电话强制中断B正在忙碌的事情让B更加容易接受。11.3.1DatagramPacketUDP通信相关的处理类是DatagramPacket类,该类位于java.net包下。该类在接收方和发送方创建的对象是不同的,当发送的时候,用户不仅要将需要发送的数据告诉DatagramPacket,还需要将数据发送的地址和端口号告诉DatagramPacket对象;接收方则只需要声明需要获取的数据即可。DatagramPacket中常用的方法如表11-1所示。方法声明功能描述DatagramPacket(byte[]buf,intlength)创建时指定封装的字节数据和长度大小,用于数据接收方DatagramPacket(byte[]buf,intoffset,intlength)创建时指定封装的字节数据、数据的偏移量和读取长度,用于数据接收方DatagramPacket(byte[]buf,intlength,InetAddressaddr,intprot)创建时指定封装的数据、封装数据的大小、指定数据包的IP地址和端口号,用于数据发送方DatagramPacket(byte[]buf,intoffset,intlength,InetAddressaddr,intprot)创建时指定封装的数据、数据的偏移量、封装数据的大小、指定数据包的IP地址和端口号,用于数据发送方InetAddressgetAddress()返回DatagramPacket对象的IP地址,如果是发送方,则返回接收方的IP地址,如果是接收方,则返回发送方的IP地址intgetOffset()返回要发送的数据的偏移量或接收到的数据的偏移量intgetPort()同getAddress类似,用于返回端口号voidsetPort()设置发送此数据包的远程主机上的端口号byte[]getData()用于返回将要发送或者接收的数据信息,发送方返回发送数据,接收方返回接收数据byte[]setData(byte[]buf)设置此数据包的数据缓冲区intgetLength()返回将要发送或接收数据的长度表11-1DatagramPacket中常用的方法Packet是打包的意思,仅仅使用打包对象,它只能将数据打包,数据的发送和接收则需要使用到另一个对象DatagramSocket。11.3.2DatagramSocketDatagramSocket对象专用于发送和接收使用DatagramPacket打包后的数据。两者分工明确,前者负责接收和发送经过后者打包的数据,后者则专门负责数据的打包工作。DatagramSocket中常用的方法如表11-2所示。方法声明功能描述DatagramSocket(intport)构造数据包套接字并将其绑定到本地主机上的指定端口DatagramSocket(intport,InetAddressladdr)创建一个数据包套接字,绑定到指定的本地地址DatagramSocket(SocketAddressbindaddr)创建一个数据包套接字,绑定到指定的本地套接字地址voidconnect(InetAddressaddress,intport)将套接字连接到此套接字的远程地址voiddisconnect()断开链接intgetReceiveBufferSize()获取此DatagramSocket的SO_RCVBUF选项的值,即平台在此DatagramSocke
本文标题:JAVA第11章-网络编程
链接地址:https://www.777doc.com/doc-7318198 .html