版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2020年8月17日,第6章 UDP数据报套接字编程,UDP数据报套接字编程主要包括DatagramPacket、DatagramSocket和MulticastSocket三个类的创建与使用。DatagramPacket类描述数据报的地址信息,DatagramSocket类表示客户机和服务器数据报套接字,MulticastSocket类则描绘了能进行多点传送的数据报套接字。这三个类均位于包中。 本章的重点是应用用户数据报协议(User Datagram Protocol,UDP)方式实现异地间各种数据的传输,主要讨论Java环境下如何实现UDP数据报套接字编程问题。,6.1 UDP通信概述,
2、用户数据报协议(UDP)是很多应用程序常用的传输协议。也就是说,UDP是在计算机上规定用户以数据报方式进行通信的协议,它提供了应用程序之间传送数据报的基本机制。,1UDP协议的特点 1)UDP向应用系统提供了一种发送封装原始IP数据报的方法,并且在发送时无需建立连接。这不仅避免了建立连接和释放连接的麻烦,而且也减少了开销和发送数据之前的时延。 2)利用协议端口,UDP能够区分在同一台主机上运行的多个应用进程;使用校验和机制,UDP协议在把数据向应用进程提交之前,先对数据做一些差错检查。 3)UDP用户数据报只有8 B的头部开销,比TCP的20 B头部要短得多。 4)UDP不使用拥塞控制,不提供
3、端到端的确认和重传功能,也不保证数据报一定能到达目的端,因此称为不可靠协议。所以主机也不需要维持具有许多参数、复杂的连接状态表。 5)通过UDP可以发送组播数据,所以使用组播服务的应用程序都建立在UDP之上。 6)不同的网络应用使用不同的协议。例如,HTTP使用TCP,而普通文件传输协议(Trivial File Transfer Protocol,TFTP)则使用UDP。UDP现在还常用于多媒体通信,如IP电话、实时视频会议、流式存储音频与视频等。,2UDP数据报套接字通信 在服务器和客户机之间传递信息有两种方式,一是建立连接的通信方式,它首先需要先建立连接,然后再传递数据,所有的数据是以包
4、(packet)的形式按照一定的顺序发送和接收的,最后关闭连接,这一通信过程是由管道(channel)来保证的。另一种是无连接的通信方式,这种方式不建立连接,而是在服务器和客户机之间利用UDP数据报来发送和接收相互独立的数据包。在这种无连接通信(UDP方式)中,所有的包都需要包含有该包完整的源和目标信息,以便指明该数据包的走向。,javanet包中的DatagramPacket类、DatagramSocket类和MulticastSocket类等为编写应用于网络之间UDP方式的数据通信实例提供了便利。在Java网络UDP数据报套接字编程中,在网络上发送和接收数据包需要使用J类库中提供的这些类。
5、简单地讲,使用DatagramSocket类和DatagramPacket类来编写发送端和接收端程序就可以实现数据报的发送和接收。使用数据报通信模式在准备接收一个数据报时,接收端只需要提供一个缓冲区,以便存放接收到的数据,缓冲区的最大容量仅受限于允许的数据报包大小,一般小于64 KB。数据包抵达时,通过DatagramSocke类作为信息起源地的IP地址以及端口号会自动初始化。在发出一个数据包时,DatagramPacket类不仅需要包含正式的数据,也要包含IP地址以及端口号,以决定数据包到达的目的结点。,6.2 DatagramPacket类,DatagramPacket类是进行数据报通信的
6、基础,用于处理报文,它将Byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成Byte数组。DatagramPacket类的对象代表了一个UDP数据包。通过UDP发送数据时,先要根据发送的数据生成一个DatagramPacket对象,然后通过DatagramPacket对象的send()方法发送这个对象。接收时,先要根据接收数据的缓冲区生成一个public final class DatagramPacket extends ObjectDatagramPacket对象,然后通过DatagramPacket对象的receive()方法接收这个对象的数据内容。,6.2.1 构造函数,1
7、接收数据报的构造函数 public DatagramPacket(byte buffer, int length); public DatagramPacket(byte buffer, int offset, int length); 其中,buffer是接收数据报的缓冲区,length为数据报中数据的字节数(数据包长度),offset指明数据报的位移量。这两个构造函数功能是由接收缓冲区(byte字节数组与它的长度length)构造一个用于接收数据报的DatagramPacket类,从网络接收数据。若用于发送,则该UDPSocket应是一个“连接型”UDPSocket。,2发送数据报的构造函
8、数 public DatagramPacket(byte data, int length, InetAddress destination, int port); public DatagramPacket(byte data, int offset, int length, InetAddress destination, int port); public DatagramPacket(byte data, int length, SocketAddress destination, int port); public DatagramPacket(bytedata, int offse
9、t, int length, SocketAddress destination, int port); 其中,数组data中存放所要发送的数据报数据,length为数据报中数据的长度,InetAddress destination或SocketAddress destination指明包发往的目的主机地址,int port是该目的主机的端口号,offset指明数据报的位移量。,6.2.2 DatagramPacket类的常用方法,DatagramPacket有许多获取数据报不同部分的get方法,包括获取实际的数据以及首部的几个字段,如表6-1所列。这些方法主要用于从网络接收的数据报。为在创建
10、数据报之后改变数据、远程地址和远程端口,Java还提供了几个set方法。,1get方法示例 为了熟悉给出的这些get方法,以显示DatagramPacket中的信息,编写example6-1程序示例代码DatagramExample。,2set方法示例 在有些情况下,重用对象比构造新的对象能显著提高网络传输性能。譬如public void setData(byte data,int offset,int length)方法是一个重载的setData()方法,它通过改变UDP数据报的有效载荷,提供了一种发送大量数据的途径。与发送新数组不同,可以将所有数据放在一个数组中,每次替换一部分。,6.3
11、DatagramSocket类,DatagramSocket类提供了访问数据报套接字的方法,通过数据报套接字可以发送、接收UDP数据包。要收发DatagramPacket,必须打开一个数据报Socket。在包中,数据报Socket通过DatagramSocket类创建和访问: Public final class .DatagramSocket extends java.lang.Object 所有数据报Socket都绑定于一个本地端口,在这个端口侦听入站数据,它也被放置在出站数据报的首部。如果编写一个客户机,不需要关心本地端口,就可以调用一个构造函数,让系统来分配一个未使用的端口(即匿名端口
12、)。该端口号放置在所有出站数据报中,服务器将用它来确定所有响应数据报的发送地址。如果要编写一个服务器,客户机端需要知道该服务器侦听入站数据报的端口。因此,当服务器使用构造DatagramSocket时,要指定侦听的本地端口。但是,客户机与服务器使用的Socket是一样的,区别只在于是使用匿名端口还是熟知端口。,6.3.1 构造函数,1public DatagramSocket() throws SocketException 该构造函数创建一个数据报套接字并将其绑定到本地主机上的匿名端口。例如在发起与服务器对话的客户机中可以使用如下代码段构造函数: try DatagramSocket cli
13、ent = new DatagramSocket( );/发送数据包 catch (SocketException ex) System.err.println(ex); 显然,在这种情况下,无需关心Socket绑定哪个端口,因为服务器会将其响应发送到数据报发起的端口。可以用同一个Socket接收服务器发回的数据报。如果无法创建Socket就抛出一个SocketException异常。,2public DatagramSocket(int port) throws SocketException 其中,port指明socket所使用的端口号,如果未指明端口号,则把socket连接到本地主机上一
14、个可用的端口。该构造函数创建一个在由port参数指定端口侦听入站数据报的套接字。使用此构造函数可以编写在熟知端口侦听的服务器。如果服务器在匿名端口侦听,客户机就无法与之联系。如果无法创建Socket,就抛出一个SocketException异常。有趣的是,对于两个无关的服务器或客户机,如果一个使用UDP而另一个使用TCP,它们可以使用相同的端口号。譬如,利用该构造函数可以设计一个端口扫描器UDPPortScanner,寻找出本地主机中正在使用的UDP端口。如果DatagramSocket构造函数抛出异常,则确定此端口正在使用。,3public DatagramSocket(int port,
15、InetAddress laddr) throws SocketException 该构造函数主要用于多穴主机,即由服务器使用。它在指定的IP地址和端口号上创建一个UDP数据报套接字,也就是说,只能通过这个特定的网络接口卡发送和接收UDP数据包。其中,port参数是Socket侦听数据报的端口。laddr参数是匹配该主机某个网络接口的IP地址。给出端口号时要保证不发生端口冲突,否则会生成SocketException类异常。如果无法创建Socket,就抛出一个SocketException异常。导致该构造函数创建失败有三个常见的原因:指定端口已经被占用;试图在Unix系统中连接低于1024的端
16、口而没有root权限;laddr不是系统网络接口之一的IP地址。,6.3.2 DatagramSocket类的常用方法,DatagramSocket类是用来发送数据报的套接字,它通过UDP套接字方式进行数据报通信。因此,DatagramSocket类的首要任务就是接收、发送UDP数据报。DatagramSocket()构造函数构造一个用于发送数据包的DatagramSoket()类。DatagramSocket(int)构造函数构造一个用于接收数据包的DatagramSocket类。当构造完成DatagramSocket类后,就可以发送和接收数据包了。DatagramSocket类的常用方法如
17、表6-2所列。,1发送数据报 public void send(DatagramPacket dp) throws IOException 其中,参数dp是将要发送的 DatagramPacket。一旦创建了DatagramPacket和DatagramSocket,就可以通过将包传递给Socket的send()方法发送该包。DatagramPacket 包含的信息指示有:将要发送的数据、其长度、远程主机的IP地址和远程主机的端口号。例如,假设theSocket 是一个DatagramSocket对象,theOutput是一个DatagramPacket对象,则可以这样使用theSocket发
18、送theOutput: theSocket.send(theOutput); 如果发送数据出现问题,可能抛出IOException异常。,2接收数据报 public void receive(DatagramPacket dp) throws IOException 该方法从网络接收一个UDP数据报,参数dp是要放置传入数据的 DatagramPacket。当此方法返回时,DatagramPacket 的缓冲区填充了接收的数据。数据报也包含发送方的 IP 地址和发送方计算机上的端口号。与ServerSocket类的accept()相似,此方法在接收到数据报前一直阻塞调用线程,直到数据报到达。如
19、果程序除了等待数据报外还有其他操作,应当在单独的线程中调用receive()。,3管理连接 在默认情况下,TCP流式套接字与UDP数据报套接字可以与任何结点通信。但这并不是人们所期望的,通常需要有选择地允许某些主机收发数据报,拒绝其他主机的包。 (1)public void connect(InetAddress address int port) 其中,参数address表示套接字的远程主机地址;port表示套接字的远程主机端口。该connect()方法将套接字连接到此套接字的远程主机地址和端口。当套接字连接到远程主机地址时,包就只能从该地址和指定的端口发送或接收包。默认情况下不连接数据报套
20、接字。,6.4 UDP数据报通信基本模式,与TCP流式套接字通信不同,UDP是面向无连接的、不可靠的、基于数据报的传输。但UDP数据报的通信基本模式仍然采用典型的客户机/服务器模式。,6.4.1 发送UDP数据包,1创建待发送的数据包 首先用DatagramPacket类将数据打包,即用DatagramPacket类创建一个对象,称之为数据包。通常采用如下构造函数创建待发送的数据包: public DatagramPacket(byte data, int length, InetAddress destination, int port); 这样所创建的数据包对象具有两个性质:一是含有dat
21、a数组指定的数据;二是数据包所要发送的目标地址是destination、目标端口号为port的主机。,若采用如下构造函数创建待发送的数据包: public DatagramPacket(byte data, int offset, int length, InetAddress destination, int port); 所创建的数据包对象将含有从指定offset开始指定长度的数组data中数据。该数据包将发送到目的地址是destination、目的端口号为port的主机上。,2发送数据包 用DatagramSocket类的不带参数的构造函数DatagramSocket()创建一个对象,该
22、对象负责发送数据包。例如,调用DatagramSocket发送UDP数据包的代码段如下: DatagramSocket socket = new DatagramSocket(2060); DatagramPacket packet = new DatagramPacket( new byte256, 256 );,使用UDP数据报通信时,可以使用接收UDP数据包的同一接口(DatagramSocket)来发送UDP数据包。当发送包时,应用程序需要构造DatagramPacket类,指定要发送的数据、数据长度、接收主机地址及端口号,并把输出数据写入这个DatagramPacket类的字节数组。
23、如果应答已接收到的包,那么地址和端口信息已经被存储,只需改写数据。然后调用DatagramSocket类中的send()方法来完成发送UDP数据报,如图6-6所示。,6.4.2 侦听接收UDP数据包,使用UDP数据报通信时,在接收端和发送端都需要创建并运行各自的Java语言程序。在应用程序能够读取由远程主机发送给它的UDP包之前,接收端首先要建立一个接收的DatagramSocket类,把套接字绑定到本地UDP端口上,并构造一个DatagramPacket类指定接收的数据缓冲区。,图6-7给出了处理UDP数据报的包通过DatagramSocket类被接收,并被转换为DatagramPacket
24、类,以及与实际应用进程之间的关系。,当处理UDP包时,应用程序必须直接操作字符数组。如果应用程序适合读取文本,可以使用Java的I/O类,在字节数组与其他流类型或读取器之间转换。比如,通过ByteArrayInputStream与数据报的内容连接起来,接着与另一种类型的InputStream或InputStreamReader连接,就可以比较容易地访问UDP包的内容了。如图6-8所示,描述了应用输入流简化从UDP包中读取数据的操作。,6.4.3 发送和接收UDP数据包程序示例,Java程序利用UDP进行通信时具有如下一些特性: 在UDP数据报通信中,通信双方之间并不要建立连接,只要双方应用程序
25、建立数据报通信DatagramSocket,构建数据报文包DatagramPacket,即可以接收和发送UDP数据报。 DatagramSocket对象构造一个UDP方式的连接;DatagramPacket对象封装UDP需要传输的数据以及数据包的长度、目的地址、目的端口,即将要发送的数据和包的目的地址等信息存放在DatagramPacket对象中。 创建DatagramSocket和DatagramPacket对象之后,就可以发送数据了。通过调用DatagramSocket对象中的send()方法实现发送,它以DatagramPacket对象为参数,将封装的DatagramPacket对象中的
26、数据组成UDP数据包发出。 接收数据需要创建一个新的DatagramPacket对象。在创建该对象时需要指明存放接收UDP数据包的缓冲区和长度,通过调用DatagramSocket对象的receive()方法完成接收数据的工作;在收到的UDP数据包中除数据外还包含发送端的IP地址、端口号等信息。 当通信结束后,调用DatagramSocket对象的close()方法关闭数据报通信。 由于服务器端应用程序要面向网络中的所有计算机,所以服务器端的应用程序收到一个UDP数据包后要对其进行分析,以获得UDP数据报的源地址信息,正确创建返回结果的数据报文给客户机。,1接收UDP数据包程序示例 接收UDP
27、数据包示例PacketReceive将绑定到一个本地端口,读取UDP数据包,并显示这个UDP数据包的内容、IP地址及端口信息。PacketReceive程序代码为: /Chapter 6, example6-5,PacketReceive 2发送UDP数据包程序示例 发送UDP数据包程序示例程序代码为: /Chapter 6, example6-6,PacketSend,编译、运行PacketReceive结果,编译、运行PacketSend结果,6.5 基于UDP的简单客户机/服务器设计,前面讨论了如何发送和接收单个UDP数据包的一些技术,但作为应用程序这远远不够,需要的是发送和接收一系列的
28、UDP数据包,而不是单个包。本节重点讨论怎样构建UDP客户机和UDP服务器,因为它们是长时间运行的系统,在运行期内需要处理许多事务。,6.5.1 构建回显客户机和回显服务器,所谓回显服务就是允许在熟知端口(端口7)上回显UDP数据包的内容,即向服务器发送数据包且将结果读回客户机。 1构建回显服务器 /Chapter 6, example6-7,EchoServer 2构建回显客户机 /Chapter 6, example6-8,EchoClient,3运行回显客户机和服务器,EchoClient编译、运行结果,EchoServer编译、运行结果,6.5.2 简单UDP客户机和服务器程序设计,设
29、计一个UDP服务器在6060端口上接收任何一个UDP客户机的UDP数据包。客户机向服务器发送任意的字符串,服务器收到字符串后,向客户机发回该字符串字符的个数。当客户机发送“bye”字符串时,结束通信。,1UDP服务器程序示例代码 /Chapter 6, example6-9,UDPServer 2UDP客户机程序 /Chapter 6, example6-10,UDPClient,UDPClient编译、运行结果,UDPServer编译、运行结果,6.6 网络组播通信,到目前为止,所讨论的Socket仅提供点对点的通信,称之为单播(Unicast)。单播Socket在两个明确定义的端点之间创建
30、一个连接。尽管点对点通信有很多用途,但在许多情况下,人们还需要将数据信息传递给预先选定的一组人或者所有人的通信方式;前者称为组播或多播,后者称为广播。譬如远程(电话)会议、网络视频会议、视频点播等,一个源端可能希望同时向多个目的端发送报文。在组播中,使单个源结点能够向其他网络结点的一个子集发送报文的副本;而广播则提供从一个源结点到网络中的所有其他结点交付报文的服务。随着Internet网络带宽的不断提高和网络通信质量的不断提高,组播传递技术越来越多地应用于网络传输。,IP协议支持IP组播。IP地址分为A、B、C、D和E五类,D类地址就是组播地址,从到
31、55,其中保留未用。组播通信是一对多的。Internet的组播可以是本地级的,也可以是全局级的。在本地级,一个局域网上的一些主机可构成一个组播组,并指派一个组播地址。所谓组播组就是一组共享组播地址的主机。在全局级,不同网络上的主机可构成一个组播组,并指派一个组播地址。当然全局级组播需要路由器的支持。在Internet中已经指派的一些组播地址有:(指本地子网上的所有系统),(指本地子网上的所有路由器);另外还指派了一些永久组播地址,譬如,音频新闻组播的永久组播地址为。任何发送给组播组地址的数据都会中继给组中的所有成员。组播组
32、中的成员是开放的;主机可以在任何时候进入或离开组。要创建一个新的组播组,所要做的工作就是在到55之间随机选择一个地址,为该地址构造一个InetAddress,并开始发送数据。,6.6.1 MulticastSocket类,在Java中,要使用MulticastSocket类来完成数据组播,这是.DatagramSocket的一个子类: public class MulticastSocket extends DatagramSocket MulticastSocket类继承了UDP DatagramSocket类,是对UDP DatagramSock
33、et类的扩展,它增加了组播的一些特定操作。因此,可以通过DatagramSocket类的send()方法在网络上发送。组播包就是UDP数据报包。,1. 构造函数 构造函数也很简单,每个构造函数都会调用DatagramSocket超类中的对应构造函数。 (1) Public MulticastSocket() throws SocketException 该构造函数创建一个绑定于匿名端口的Socket。这对于客户机(即发起数据传送的程序)很有用,因为它们不需要使用熟知端口:接收端依赖于数据报包中所包含的端口。如果需要知道端口号,可以用继承自DatagramSocket的getLocalPort(
34、)方法查看。如果无法创建Socket,则此构造函数抛出一个SocketException异常。,(2)Public MulticastSocket( int port) throws SocketException 该构造函数创建一个在熟知端口接收数据报的Socket。其中port参数指定Socket侦听数据报的端口。如果无法创建Socket,则此构造函数抛出一个SocketException异常。如果没有绑定于端口的足够特权,或者试图绑定于已经使用的端口,就无法创建Socket。由于组播Socket是与操作系统有关的数据报Socket,所以MulticastSocket不能占据已经由Data
35、gramSocket占据的端口,反之亦然。,(3)Public MulticastSocket(SocketAddress bindAddress) throws IOException 自Java1.4开始,可以使用SocketAddress对象创建一个MulticastSocket。如果SocketAddress绑定于一个端口,那么它与前一个构造函数就非常类似。,2. 与组播组通信相关的常用方法 一旦创建了MulticastSocket,就可以通过执行加入组播组、向组播成员发送数据、接收组中数据、以及离开组播组等方法完成组播组通信的任务。表6-4列出了MulticastSocket类的常用
36、方法。,6.6.2 网络组播编程示例,网络组播通信可以使用组播(MultiCast)技术。在服务器上,应用进程打开一个端口,发送UDP数据报包,UDP数据报包中包含了多播地址,表明是哪个组播组。在客户机上,每个客户机应用进程侦听相应的端口,并加入组播组,便可以接收网络上该端口该组播组的广播了。,1组播服务器程序示例 组播服务器的编程步骤及其方法为: (1)创建DatagramSocket对象 DatagramSocket socket = new DatagramSocket(); (2)创建组播组(InetAddress对象) InetAddress group = InetAddress.
37、getByName(); 其中为多播地址,可在到55多播地址范围内选择。 (3)生成UDP数据包 DatagramPacket datapacket = new DatagramPacket(buffer,buffer.length, group, port); (4)发送数据包 socket.send(datapacket); 使用DatagramSocket类的send()方法发送。,2组播客户机程序示例 组播组客户机的编程步骤及其方法为: (1)创建MulticastSocket对象,并与服务器的端口绑定 M
38、ulticastSocket mcsocket = new MulticastSocket(6060); 其中的6060必须与服务器中第一步所有端口号相同。 (2)创建组播组(InetAddress对象) InetAddress group = InetAddress.getByName(); 其中为组播地址,可在到55组播地址范围内选择。 (3)加入组播组 mcsocket.joinGroup(group); 使用MulticastSocket类的joinGroup()方法。 (4)生成UDP数据报 DatagramPacket rdp = new DatagramPacket(buffer,buffer.length); 其中,buffer 为byte类型的数组。 (5)接收组播数据包 mcsocket.receive(rdp); (6)获取组播数据包 String rmdata = new String(rdp.getData(); 通过UDP数据报的getData()方法获取接收到的字符串。,MulticastUDPServer编译、运行结果,MulticastUDPClient编译、运行结果,编写一个Java组播程序需要以下过程: 创建一个需要发送的按规定编址的Datagr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025中国能建新疆院校园招聘(56人)笔试历年参考题库附带答案详解
- 2025上控(青岛)水务发展有限公司招聘相关人员4人(山东)笔试历年参考题库附带答案详解
- 2026年江苏省高三考前地理模拟试卷及答案
- 4.1 我国的个人收入分配 课件统编版高中政治必修二 经济与生活
- 2026 二年级上册《学系红领巾》课件
- 2026五年级上《冀中的地道战》教学课件
- 汽车机械基础课件 齿轮传动的失效形式、设计准则及材料选用
- 快递车辆消杀制度
- 建立算法备案和审计制度
- 2026年汽车代售合同(1篇)
- 某1.8万方反硝化深床滤池设计计算书
- 2024届浙江省名校协作体高三下学期开学联考物理试题及答案
- 2024年广东佛山市南海区大沥镇镇属企业招聘笔试参考题库含答案解析
- 100部经典好看韩国电影大全
- 新版医院住院病案首页
- C919客机机组培训-指示记录
- 2023年华侨、港澳、台联考高考物理试卷(含解析)
- 2023年广东中山市文化广电旅游局所属事业单位(孙中山故居纪念馆)招考聘用笔试题库含答案解析
- 2023化工总控工(高级)技能理论考试核心题库500题(含各题型)
- 轮毂加工工艺规程及专用车夹具设计
- 售楼部装修施工方案设计
评论
0/150
提交评论