摘要本文介绍了UDP Sockets的基本概念和IP多点传送的原理详细讨论了Java中的相关类及使用方法提供了一个IP多点传送的开发流程 关键词JavaUDP Sockets 一IP多点传送 IP多点传送(multicast delivery)是针对点到点的传送和广播传送两种方式而言的它是指在一定的组内对其成员进行的广播是一种有限的广播组中的某个成员发出的信息组中的其它所有成员都能收到它是UDP Sockets的一个分支 IP多点传送特别适合与高带宽的应用例如在网络上发送视频和音频随着网络带宽的不断提高和网络通讯质量的不断改善IP多点传送还将广泛地被应用于网上聊天及网上会议分布式数据存储联机事务处理交互式游戏等方面另外多点传送还可以被客户机用于在网络上寻找相应的服务器客户机发送一个多点传送的请求任何监听服务器都可以与客户机连接并开始一个事务 二UDP Socket基础 使用用户数据报协议(User Datagram Protocol简称UDP)进行会话必须将信息装配成一定尺寸的小报文当发送一条信息接收方能否收到并返回信息永远是不确定的如果无法收到返回信息我们就无法确定我们发送的信息是否被接收——它可能在途中丢失接收者返回的响应信息也可能丢失另外接收者也可能忽略我们的信息因此UDP被描述为不可靠的无连接的和面向消息的 创建UDP sockets非常象创建一个邮箱邮箱是使用地址来识别的但是我们不需要为每个发送信息的人构造一个新的邮箱可以在含有发送信息的明信片上写上目的地址将其放在邮箱中并发送出去接收者可能会长久的等待直到含有信息的明信片到达它的邮箱而明信片上标识了发送者的返回地址 三IP多点传送的原理 为了支持IP多点传送某些范围的IP地址被单独留出专门用于这个目的这些IP地址是D类地址其地址的最高四比特的位模式为即IP地址的范围在和之间它们中的每一个IP地址都可以被引用作为一个多点传送组任何以该IP地址编址的IP报文将被该组中的其它所有机器接收也就是说一个IP地址就相当于一个邮箱另外组中的成员是动态的并随时间而改变 对于IP多点传送网间网组管理协议(Internet Group Management Protocol简称IGMP)用于管理多点传送组中的成员支持多点传送的路由可以使用IGMP决定本地的机器是否赞成加入某个组一个多点传送路由可以决定是否转发一个多点传送报文 影响多点传送报文的一个重要参数是time-to-live(TTL)TTL用于描述发送者希望传送的信息能通过多少不同的网络当报文被路由器转发报文中的TTL将减一当TTL为零时报文将不再向前发送 在实际使用中我们必须注意下面几点 这些IP地址只能作为信宿地址使用绝对不能出现在任何信源地址域中也不能出现在源路径或记录路径选项中 由于IP多点传送是一对多的传送因此不能利用差错与控制报文协议(Internet Control Message Protocol简称ICMP)产生出错报文 发送一个信息到一个组发送主机可以不是组中的成员 一些组被Internet Assigned Numbers Authority(IANA)分配保留用于特殊的目的详情参见ftp://ftpinternicnet/rfc/rfctxt另外避免使用一些保留组从到仅限于本地子网使用建议在和之间任意选取一个IP地址 如果我们选取的组已经被使用与其他机器的通讯将会混乱一旦发生可以退出应用试试其他的地址 当一个机器加入一个多点传送组它将开始接收该IP多点传送地址的信息如果多点传送报文分发到网络上任何监听该信息的机器都会有机会接收它对于IP多点传送没有一个机制对相同网络上的机器能否加入该多点传送组加以限制因此安全性是我们必须考虑的问题之一 选择的TTL参数应尽可能小一个大的TTL值会不必要地占用Internet带宽此外还可能破坏不同区域使用相同组的其它的多点传送通讯 四Java中与IP多点传送相关的类 javanet包中含有UDP通讯所需要的工具其中包括IP多点传送 1DatagramPacket类 我们可以使用DatagramPacket类创建一个用于发送的数据报而当接收UDP数据报时可以使用DatagramPacket类读取数据报中的数据发送者及其它信息 为了创建一个数据报并发送到远地系统可以使用下面的构造器 Public DatagramPacket(byte ibufint lengthInetAddress iaddrint iport); ibuf是编码信息数据的字节数组它的长度length就是数据报放在其中的字节数组的长度iaddr是一个InetAddress对象存储着接收方的主机名和IP地址等信息iport标识数据报发送到接收主机的端口 为了接收数据报必须使用DatagramPacket构造器其原型为 public DatagramPacket(byte ibufint ilength); ibuf是指接收的数据报的数据部分 ilength是该部分数据的长度如果 ilength 小于机器接收的UDP数据报的尺寸多余的字节将被Java忽略 另外类中有一些方法(method)可以让我们得到一些相关的信息 public int getLength(); //得到数据报中数据块的字节尺寸 public bytegetData(); //得到接收数据报中的数据 public InetAddress getAddress(); //为发送者提供一个 InetAddress对象 public int getPort(); //得到UDP端口 值得注意的是TCP sockets的编程中我们无须将传送的数据分块然而当我们创建一个基于UDP的网络通讯应用程序时必须创建一套方法在运行时刻决定需分割的数据报的长度对于TCP/IP最大的数据报可以含有字节的数据然而主机仅能接收最多字节的数据支持字节的大数据报的平台是利用IP层对数据报进行分割的如果在传送期间任何含有IP报文的一个数据块丢失都会造成整个UDP数据报的丢失因此我们在确定应用中数据报尺寸时对其尺寸的合理性一定要谨慎 下面就是分割数据的一个例子 //循环地从输入流input中读一行数据 while((nextLine=inputreadLine())!=null){ //定义一个空数据报其尺寸为 mcastBuffer=new byte[]; //如果读入的数据的长度大于定义的数据报的长度 //则使用定义的长度否则使用读入数据的长度 if(nextLinelength()>mcastBufferlength){ sendLength=mcastBufferlength; }else { sendLenth=nextLinelength(); } //将读入的数据转换为byte类型 lineData=nextLinegetBytes(); //将数据复制到用于创建数据报的byte数组 for(int i=;i mcastBuffer[i]=lineData[i]; } ……创建数据报发送或接收…… } 2MulticastSocket类 Java的 MulticastSocket类是实施IP多点传送网络特征的关键它允许我们使用多点传送IP发送或接收UDP数据报 MulticastSocket的构造器为 public MulticastSocket () throws IOException; //创建一个多点传送socket public MulticastSocket(int port)throws IOException; //在指定端口创建一个多点传送socket 另外类中其它常用的方法有 public void joinGroup(InetAddress mcastaddr)throws IOException{} //加入多点传送组 public void leaveGroup(InetAddress mcastaddr)throws IOException{} //离开多点传送组 public synchronized void send(DatagramPacket pbyte ttl) throws IOException{}//发送数据报 public synchronized void receive(DatagramPacket pbyte ttl) throws IOException{} //接收数据报 创建一个DatagramPacket对象之后我们必须相应地创建一个 MulticastSocket对象这样数据报就可以使用send()方法发送了下面的代码演示了如何创建 MulticastSocket发送和接收IP多点传送数据报 int multiPort=; //定义端口号非超级用户应使用以上的端口 int ttl=; //设定TTL值 InetAddress multiAddr=InetAddressgetByName(″″)//设定多点传送IP byteSmultiBytes={HeO}; //定义一个内容为Hello的数据报 //创建多点传送数据报 DatagramPacket SmultiDatagram new Datagram Packet(SmultiBytesSmultiByteslengthmultiAddrmultiPort); MulticastSocket multiSocket=new MulticastSocket(); //创建多点传送socket multiSocketsend(SmultiDatagramttl)//发送数据报(不加入到组中) …… byteRmultiBytes=new byte[];//定义一个空数据报长度为字节 //创建接收数据报 DatagramPacket RmultiDatagram=new DatagramPacket(RmultiBytesRmultiByteslength); multiSocketjoinGroup(multiAddr);//加入到多点传送组中 multiSocketreceive(RmultiDatagram);//接收UDP数据报 …… multiSocketleaveGroup(multiAddr);//离开多点传送组 multiSocketclose(); //关闭多点传送 socket 当调用joinGroup()方法时机器将关注沿着网络传送属于特定多点传送组的任何IP报文也就是说机器拥有了一个邮箱主机还应使用IGMP相应地报告组的使用对于多IP地址的机器应配置数据报发送的接口setInterface(oneOfMyLocalAddrs); 在DatagramSocket中没有类似 setSo Timeout()的方法设置超时 五IP多点传送应用程序的开发流程 由于IP多点传送主要用于同组中成员的交流因此应用程序的开发流程大体如下 创建一个需发送的按规定编址的数据报DatagramPacket; 建立一个用于发送和接收的MulticastSocket; 加入一个多点传送组 将数据报放入MulticastSocket中传送出去 等待从MulticastSocket接收数据报 解码数据报提取信息 根据得到的信息作出回应 重复—步 离开该多点传送组关闭MulticastSocket 六结束语 在实际应用中发送和接收数据建议分别以单独的线程同时运行另外如果需在屏幕上显示建议使用两个线程在两个不同的窗口分别负责显示发送的数据和接收的数据 |