数据报套接字

上传人:无*** 文档编号:209165983 上传时间:2023-05-12 格式:PPT 页数:67 大小:850KB
返回 下载 相关 举报
数据报套接字_第1页
第1页 / 共67页
数据报套接字_第2页
第2页 / 共67页
数据报套接字_第3页
第3页 / 共67页
点击查看更多>>
资源描述
第第5章章 数据报套接字数据报套接字 5.1数据报套接字概述5.2DatagramSocket编程示例5.3组播套接字5.4组播套接字编程示例Network ProgrammingSoftwareEngineeringSoftwareEngineering第第5章章 数据报套接字数据报套接字 n数据报套接字又称自寻址套接字,数据报套接字使用前不需进行连接,数据报套接字编程中每条数据报文负载了自己的地址信息,并与其它信息相互独立。在接收信息时,数据报套接字扮演的角色就是一个信箱,从不同的地址发来的信件都可以放在这里,数据报套接字一旦被创建,可以向不同的地址发信息。n数据报套接字是基于UDP协议的。n数据报套接字编程中主要使用三个类:DatagramPacket、DatagramSocket、MulticastSocket类Network ProgrammingSoftwareEngineeringSoftwareEngineering第第5章章 数据报套接字数据报套接字n基于UDP的数据报和套接字nUDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1 数据报套接字概述数据报套接字概述n数据报套接字是基于UDP协议的。它比TCP具有更快的传输速度,但是不可靠。n当网络传输UDP数据报时,无法保证数据报一定到达目的地,也无法保证各个数据报按发送的顺序到达目的地。当发送方先发送包含字符串“hello”的数据报,再发送包含字符串“everyone”的数据报,接收方有可能先接收到字符串“everyone”,再接收到字符串“hello”;也有可能什么数据也没有接收到,因为发送方发送的数据有可能在传输途中都丢失了。n在Java中,java.util.DatagramSocket负责接收和发送UDP数据报,java.util.DatagramPacket表示UDP数据报。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1 数据报套接字概述数据报套接字概述nUDP协议是无连接的协议,客户端的DatagramSocket与服务器端的DatagramSocket不存在一一对应关系,两者无需建立连接,就能交换数据报。n每个DatagramSocket与一个本地地址(包括本地主机的IP地址和本地UDP端口)绑定,每个DatagramSocket可以把UDP数据报发送给任意一个远程DatagramSocket,也可以接收来自任意一个远程DatagramSocket的UDP数据报。在UDP数据报中包含了目的地址的信息,DatagramSocket根据该信息把数据报发送到目的地。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1 数据报套接字概述数据报套接字概述Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.1 创建DatagramPacket对象nDatagramPacket表示数据报,它的构造方法可以分为两类:n一类构造方法创建的DatagramPacket对象用来接收数据n还有一类构造方法创建的DatagramPacket对象用来发送数据。n两类构造方法的主要区别是,用于发送数据的构造方法需要设定数据报到达的目的地址,而用于接收数据的构造方法无需设定地址。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.1 创建DatagramPacket对象1、用于接收数据的构造方法包括:(1)publicDatagramPacket(bytedata,intlength)(2)publicDatagramPacket(bytedata,intoffset,intlength)n以上data参数用来存放接收到的数据,参数length指定要接收的字节数,参数offset指定在data中存放数据的起始位置,即dataoffset。如果没有设定参数offset,那么起始位置为data0。n举例:Bytebuffer=newbyte8912DatagramPacketdatap=newDatagramPacketbuffer,buffer.lengthNetwork ProgrammingSoftwareEngineeringSoftwareEngineering5.1.1 创建DatagramPacket对象2、用于发送数据的构造方法包括:(1)public DatagramPacket(byte data,int offset,int length,InetAddress address,int port)构造长度为length偏移量为offset,包发送到指定主机端口号的发送数据包(2)public DatagramPacket(byte data,int offset,int length,SocketAddress address)构造将长度为length偏移量为offset,发送到指定套接字地址(主机+端口号)的发送数据包Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.1 创建DatagramPacket对象(3)publicDatagramPacket(bytedata,intlength,InetAddressaddress,intport)构造长度为length,发送到指定主机和端口号的发送数据包(4)publicDatagramPacket(bytedata,intlength,SocketAddressaddress)构造长度为length,发送到指定套接字地址(主机+端口号)的发送数据包n以上data参数中存放了要发送的数据,参数length指定要发送的字节数,参数offset指定要发送的数据在data中的起始位置,即dataoffset。如果没有设定参数offset,那么起始位置为data0。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.1 创建DatagramPacket对象n以下两段程序代码都创建了一个数据报,它的送达地址为主机“myhost”的UDP端口100:InetAddressremoteIP=InetAddress.getByName(myhost);intremotePort=100;bytedata=hello.getBytes();/获得字符串“hello”的字符编码DatagramPacketoutputPacket=newDatagramPacket(data,data.length,remoteIP,remotePort);Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.1 创建DatagramPacket对象或者:或者:InetAddressremoteIP=InetAddress.getByName(myhost);intremotePort=100;SocketAddressremoteAddr=newInetSocketAddress(remoteIP,remotePort);bytedata=hello.getBytes();DatagramPacketoutputPacket=newDatagramPacket(data,data.length,remoteAddr);Network ProgrammingSoftwareEngineeringSoftwareEngineering选择数据报的大小选择数据报的大小nDatagramPacket的构造方法有一个参数length,它决定了要接收或发送的数据报的长度。n对于用于接收数据的DatagramPacket,如果实际接收到的数据报的长度大于DatagramPacket的长度,那么多余的数据就会被丢弃。n因此,必须为DatagramPacket选择合适的长度。n理论上,IPv4数据报的最大长度为65507个字节,如果一个DatagramPacket的长度为65507个字节,那么它就可以接收任何IPv4数据报,而不会丢失数据。n理论上,IPv6数据报的最大长度为65536字节。Network ProgrammingSoftwareEngineeringSoftwareEngineering选择数据报的大小选择数据报的大小n选择数据报大小的通用原则是:n如果网络非常不可靠,如分组无线电网络,则要选择较小的数据报,以减少传输中遭破坏的可能性。n如果网络非常可靠,而且传输速度很快,就应当尽可能使用大的数据报。n对于多数网络,8K是一个很好的折衷方案。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2 DatagramPacket的常用方法获取数据包信息方法:(1)PublicInetAddressgetAddress()返回接收或发送此数据报文的机器的IP地址。(2)PublicbytegetData()返回接收的数据或发送出的数据。(3)PublicgetintLength()返回发送出的或接收到的数据的长度。(4)PublicintgetPort()返回接收或发送该数据报文的远程主机端口号。(5)PublicSocketAddressgetSocketAddress()返回远程主机IP地址和端口号。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2DatagramPacket的常用方法设置设置DatagramPacketDatagramPacket方法:nDatagramPacket类提供了一系列set方法,用于设置各种属性:npublicvoidsetAddress(InetAddressaddr)数据包发往地址npublicvoidsetPort(intport)接收者的UDP端口npublicvoidsetSocketAddress(SocketAddressaddress)远程主机主机IP地址和端口号npublicvoidsetData(bytedata)设置数据缓存区npublicvoidsetData(bytedata,intoffset,intlength)设置数据缓存区npublicvoidsetLength(intlength)数据的长度。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2 DatagramPacket的常用方法数据格式的转换n数据报中只能存放字节形式的数据。n在发送方,需要把其他格式的数据转换为字节序列。n在接收方,需要把字节序列转换为原来格式的数据。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2 DatagramPacket的常用方法在发送方,可以利用ByteArrayOutputStream和DataOuputStream来把其他格式的数据转换为字节序列。例如以下longToByte()方法把long型数组中的数据转换为字节,把它们存放到一个字节数组中,再将其返回:publicbytelongToByte(longdata)throwsIOExceptionByteArrayOutputStreambao=newByteArrayOutputStream();DataOutputStreamdos=newDataOutputStream(bao);for(inti=0;idata.length;i+)dos.writeLong(datai);dos.close();returnbao.toByteArray();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2 DatagramPacket的常用方法在接收方,可以利用ByteArrayInputStream和DataInputStream来把字节序列转换为原来格式的数据。例如以下byteToLong()方法把byte数组中的字节转换为long型数据,把它存放到一个long型数组中,再将其返回:publiclongbyteToLong(bytedata)throwsIOExceptionlongresult=newlongdata.length/8;/一个long数据占8个字节ByteArrayInputStreambai=newByteArrayInputStream(data);/将一个字节数组字节数组当作流输入的来源DataInputStreamdis=newDataInputStream(bai);for(inti=0;idata.length/8;i+)resulti=dis.readLong();returnresult;Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2 DatagramPacket的常用方法在发送方,可以利用ByteArrayOutputStream和DataOuputStream来把其他格式的数据转换为字节序列。例如以下longToByte()方法把long型数组中的数据转换为字节,把它们存放到一个字节数组中,再将其返回:publicbytelongToByte(longdata)throwsIOExceptionByteArrayOutputStreambao=newByteArrayOutputStream();DataOutputStreamdos=newDataOutputStream(bao);for(inti=0;idata.length;i+)dos.writeLong(datai);dos.close();returnbao.toByteArray();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.2 DatagramPacket的常用方法重用DatagramPacketn同一个DatagramPacket对象可以被重用,用来多次发送或接收数据。n在例程DatagramTester类中,创建了sender和receiver两个线程。nsender线程负责发送数据,这段操作由send()方法实现。nReceiver线程负责接收数据,这段操作由receive()方法实现。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.3 创建DatagramSocket对象DatagramSocket负责接收和发送数据报。每个DatagramSocket对象都会与一个本地端口绑定,在此端口监听发送过来的数据报。在客户程序中,一般由操作系统为DatagramSocket分配本地端口,这种端口也称为匿名端口;在服务器程序中,一般由程序显式的为DatagramSocket指定本地端口。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.3 创建DatagramSocket对象DatagramSocket的构造方法有以下几种形式:Network Programming构造方法功能public DatagramSocket()public DatagramSocket(int port)public DatagramSocket(int port,InetAddress laddr)public DatagramSocket(SocketAddress bindaddr)创建绑定到本地主机上任何可用端口的数据报套接字创建绑定到本地主机上指定端口的数据报套接字创建绑定到指定主机地址和端口的数据报套接字创建绑定到指定本地套接字地址的数据报套接字SoftwareEngineeringSoftwareEngineering5.1.4 DatagramSocket常用方法如果想知道一个DatagramSocket对象所绑定的本地地址,可以调用它的以下方法:(1)intgetLocalPort():返回DatagramSocket所绑定的端口。(2)InetAddressgetLocalAddress():返回DatagramSocket所绑定的IP地址。(3)SocketAddressgetLocalSocketAddress():返回一个SocketAddress对象,它包含DatagramSocket所绑定的IP地址和端口信息。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.4 DatagramSocket常用方法(4)DatagramSocket的receive()方法负责接收一个数据报,该方法的定义如下:publicvoidreceive(DatagramPacketdatagramPacket)throwsIOException此方法从网络上接收一个数据报。如果网络上没有数据报,执行该方法的线程会进入阻塞状态,直到收到数据报为止。下面示例是接收代码UdpRecv.java:Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.4 DatagramSocket常用方法.*;publicclassUdpRecvpublicstaticvoidmain(Stringargs)throwsExceptionDatagramSocketds=newDatagramSocket(3000);bytebuf=newbyte1024;DatagramPacketdp=newDatagramPacket(buf,1024);dp.receive(ds);StringstrInfo=newString(dp.getData(),0,dp.getLength()+from+dp.getAddress().getHostAddress()+:+dp.getPort();System.out.println(strInfo);ds.close();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.4 DatagramSocket常用方法(5)DatagramSocket的send()方法负责发送一个数据报,该方法的定义如下:publicvoidsend(DatagramPacketdp)throwsIOException值得注意的是,UDP协议提供不可靠的传输,如果数据报没有到达目的地,send()方法不会抛出任何异常,因此发送方程序无法知道数据报是否被接收方接收到,除非双方通过应用层的特定协议来确保接收方未收到数据报时,发送方能重发数据报。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.4 DatagramSocket常用方法publicclassUdpSendpublicstaticvoidmain(Stringargs)throwsExceptionDatagramSocketds=newDatagramSocket();StringstrInfo=HelloTaohx;ds.send(newDatagramPacket(strInfo.getBytes(),strInfo.length(),InetAddress.getByName(59.64.157.93),3000);ds.close();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.1.5 数据报套接字编程Network Programming接收端接收端发送端发送端数据报套接字通信的流程如下:数据报套接字通信的流程如下:SoftwareEngineeringSoftwareEngineering5.1.5 数据报套接字编程数据报套接字程序设计的工作流程如下:(1)首先建立数据报套接字(2)创建一个数据报文包(3)用send方法发送数据(4)用receive方法接收数据(5)处理缓冲区数据(6)用close(方法关闭数据报套接字Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 DatagramSocket编程示例5.2.15.2.1利用数据报的利用数据报的C/SC/S程序程序服务器端接收数据.*;importjava.util.*;importjava.io.*;publicclassUDPServerpublicstaticvoidmain(Stringargs)throwsExceptionbytebuf=newbyte1000;DatagramSocketreceiveSocket=newDatagramSocket(5000);/开始监视5000端口DatagramPacketreceivePacket=newDatagramPacket(buf,buf.length);Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 DatagramSocket编程示例while(true)receiveSocket.receive(receivePacket);/阻塞,直到收到数据报后将数据装入receivePacket中System.out.println(newString(buf);Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2.1利用数据报的C/S程序(客户端发送数据)客户端发送数据).*;importjava.util.*;importjava.io.*;publicclassUDPClientpublicstaticvoidmain(Stringargs)throwsExceptionInetAddresstarget=InetAddress.getByName(“);/得到目标机器的地址实例bytebuf=newbyte1000;DatagramSocketsendSocket=newDatagramSocket(9999);/从9999端口发送数据报Stringhello=“Hello,Iamcomein!”;/要发送的数据bytebuf=hello.getBytes();/将数据转换成Byte类型sendPacket=newDatagramPacket(buf,buf.length,target,5000);/将BUF缓冲区中的数据打包sendSocket.send(sendPacket);/发送数据sendSocket.close();/关闭连接Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 DatagramSocket编程示例5.2.25.2.2基于UDP的简单java聊天室代码:这个一个简单的利用数据报协议传送信息的聊天测试程序。程序由三个简单的组件构成,分别是一个List,用于接收信息,一个JComboBox,用于输入对方ip地址,和一JTextField,用于编辑信息。聊天双方的程序必须监听同一个固定的端口,只有这样才能实现相互通信。当输入的ip地址localhost时,自己会收到自己发送的信息。由于UDP协议通信不需要使用服务器,所以用于聊天的程序只需要些一个,分别在不同的机器上运行。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 DatagramSocket编程示例Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(1 1)importjava.util.*;.*;importjava.io.*;importjava.awt.*;importjavax.swing.*;publicclassChatextendsJFramePrintStreamps=null;privateintport;/端口java.awt.Listlist=newjava.awt.List(20);/接收信息列表Vectorvector=newVector();/已发IP列表(Vector类与ArrayList类相似)JComboBoxipField=newJComboBox(vector);/发送对象ipJTextFieldtextField=newJTextField(20);/编辑发送内容DatagramSocketsocket=null;Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(2 2)publicChat(intport)this.port=port;tryps=newPrintStream(log.txt);catch(FileNotFoundExceptione)e.printStackTrace();trysocket=newDatagramSocket(port);catch(Exceptione)e.printStackTrace(ps);ContainercontentPane=this.getContentPane();ipField.setPreferredSize(newDimension(120,20);ipField.setEditable(true);Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(3 3)JPanelpanel=newJPanel();panel.setLayout(newBoxLayout(panel,BoxLayout.X_AXIS);contentPane.add(list,BorderLayout.CENTER);contentPane.add(panel,BorderLayout.SOUTH);panel.add(ipField);panel.add(textField);receive();addListener();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(4 4)/*加入并处理事件听侦*/voidaddListener()/当在textField组件中输入内容后按下回车键,即发送出输入信息。textField.addActionListener(newActionListener()publicvoidactionPerformed(ActionEvente)/sendmessagebytebuf=textField.getText().getBytes();Stringip=(String)ipField.getSelectedItem();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(5 5)tryDatagramPacketdp=newDatagramPacket(buf,buf.length,InetAddress.getByName(ip),port);socket.send(dp);if(!vector.contains(ip)vector.add(ip);catch(Exceptionex)ipField.setSelectedItem(null);ex.printStackTrace(ps);textField.setText();addWindowListener(newWindowAdapter()publicvoidwindowClosing(WindowEvente)socket.close();System.exit(0););Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(6 6)/*接收信息线程*/voidreceive()newThread(newRunnable()publicvoidrun()bytebuf=newbyte1024;while(true)Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(7 7)tryDatagramPacketdp=newDatagramPacket(buf,buf.length);socket.receive(dp);Stringmessage=newString(buf,0,dp.getLength()+from+dp.getAddress().getHostAddress()+:+dp.getPort();list.add(message,0);catch(Exceptione)if(!socket.isClosed()e.printStackTrace(ps);).start();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.2 5.2 DatagramSocketDatagramSocket编程示例(编程示例(8 8)publicstaticvoidmain(Stringargs)tryUIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName();catch(Exceptione)e.printStackTrace();createAndShowGUI();publicstaticvoidcreateAndShowGUI()Chatchat=newChat(8100);chat.pack();chat.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);chat.show();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3 组播套接字n前面节中所介绍数据报通信是在两台主机之间的点对点通信,称为“单播(Unicast)”。当多台主机同时接收一个数据报时,若采用单播通信,则源主机需要给每个接收主机发送一个相同的数据报;若采用组播通信,则源主机只需发送一个数据报即可到达每个接收主机,从而节省了网络带宽,降低了发送主机的负荷。n组播(Multicast)是一种特殊的数据报传输方式,它将具有相同需求的主机加入到某一个组,向组发送的信息,其所有成员均可接收到。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3 组播套接字n组是用组播地址(224.0.0.0-239.255.255.255此范围内的所有地址的前4个二进制位都是“1110”。组播地址也被称为D类IP地址,与其他的A类、B类和C类地址相区别。)和标准UDP端口号来标识的,即待发送数据报的目的地址为一个组播地址。主机可以申请加入某个组播地址所标识的组,也可以从该组中退出。n组播与单播UDP的区别在于,前者必须考虑TTL(TimeToLive)值,它用IP数据包的头部的一个字节表示。nTTL通过限制IP包被丢弃前通过的路由器数目,来决定IP包的生存时间。IP包每通过一个路由器,TTL就减一,当TTL变为0,这个包就被丢弃。nTTL的一个作用是防止配置有误的路由器把包在路由器之间无限的来回传递,还有一个作用是限制组播的地理范围。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3.1 创建MulticastSocket对象对象为了实现组播通信,包中有相应的MulticastSocket类。多播数据报套接字类MulticastSocket是DatagramSocket类的子类,它用来发送和接收IP多播包,同时可以沿用数据报通信的一些主要方法。和DatagramSocket一样,MulticastSocket也与DatagramPacket搭配使用,DatagramPacket用来存放接收和发送的组播数据报。n如果要接收组播数据报,只需创建一个MulticastSocket,把它加入到组播组,就能接收发送到该组的组播数据。n发送组播数据报与发送单播数据报非常相似,只需创建一个MulticastSocket,无需把它加入到组播组(当然也可以把它加入到组播组),就能向一个组播组发送数据Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3.1 创建MulticastSocket对象对象MulticastSocket类的构造方法如下:类的构造方法如下:Network Programming构造方法功能public MulticastSocket()throws IOExceptionpublic MulticastSocket(int port)throws IOExceptionpublic MulticastSocket(SocketAddress bindaddr)throws IOException创建多播套接字创建多播套接字并将其绑定到特定端口创建绑定到指定套接字地址的MulticastSocketSoftwareEngineeringSoftwareEngineering5.3.2 MulticastSocket类的常用方法创建创建MulticastSocketMulticastSocket对象后,还需要加入到指定的对象后,还需要加入到指定的组组播播组组,结结束后离开多播束后离开多播组组。MulticastSocket支持以下操作:(1)public void joinGroup(InetAddress address):加入到组播组(2)public void send(DatagramPacketpacket,bytettl):向组中成员发送数据报方法(3)public void receive(DatagramPacketpacket,bytettl):接收发送到组播组的数据报方法(4)离开组播组:leaveGroup()方法(5)publicvoidsetTimeToLive(intttl)设置ttl默认值(6)publicvoidgetTimeToLive()返回值。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3.2 MulticastSocket类的常用方法发送组包示例:tryInetAddressaddress=InetAddress.getByName(231.0.0.1);bytedata=“MulticastSocketMulticastSocket”getBytes();Intport5000;DatagramPacketdatap=newDatagramPacket(data,data.length,address,port);MulticastSocket muls=MulticastSocket();muls.send(datap);/发送组播数据报catch(IOExceptionie)Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3.3 组播套接字编程组播套接字程序设计的流程如下:组播套接字程序设计的流程如下:Network Programming接收端接收端MulticastSocket(Int port)MulticastSocket.joinGroup(InetAddress address);DatagramPacket(byte ,buf,int length)MulticastSocket.receive(DatagramPacket p);MulticastSocket.leaveGroup(InetAddress address)MulticastSocket.close发发送端送端MulticastSocket()()DatagramPacket(byte ,buf,int length)MulticastSocket.send(DatagramPacket p);MulticastSocket.closeSoftwareEngineeringSoftwareEngineering5.3.3 组播套接字编程编辑一个java组播应用程序的过程如下1.创建一个用于发送和接收的MulticastSocket组播套接字对。2.创建一个指定缓冲区大小及组播地址和端口的DatagramPacket组播数据包对象。3.使用组播套接字joinGroup(),将其加入到一个组播。4.使用组播套接字的send()方法,将组播数据包对象放入其中,发送组播数据包.或者使用组播套接字的receive()方法,将组播数据包对象放入其中,接收组播数据包Network ProgrammingSoftwareEngineeringSoftwareEngineering5.3.3 组播套接字编程5.解码组播数据包提取信息,并依据得到的信息作出响应Strings=newString(dp.getData(),0,dp.getLength();6.重复过程4和5,即在while循环中实现。7.使用组播套接字的leaveGroup()方法,离开组播组;关闭组播套接字Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4组播套接字编程示例5.4.1组播套接字组播套接字C/SC/S程序程序下面程序示范了组播套接字的基本用法组播套接字的基本用法一个客户端加入多点传送组的例子。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序/MCClient.javaimportjava.io.*;.*;classMCClientpublicstaticvoidmain(Stringargs)throwsIOExceptionMulticastSockets=newMulticastSocket(10000);InetAddressgroup=InetAddress.getByName(231.0.0.1);s.joinGroup(group);Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序for(inti=0;i10;i+)bytebuffer=newbyte256;DatagramPacketdgp=newDatagramPacket(buffer,buffer.length);s.receive(dgp);bytebuffer2=newbytedgp.getLength();System.arraycopy(dgp.getData(),0,buffer2,0,dgp.getLength();System.out.println(newString(buffer2);s.leaveGroup(group);s.close();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序MCClient创建了一个绑定端口号10000的MulticastSocket对象,接下来他获得了一个InetAddress子类对象,该子类对象包含多点传送组的IP地址231.0.0.0,然后通过joinGroup(InetAddressaddr)方法加入多点传送组中,接下来MCClient接收10个自寻址包,同时输出他们的内容,然后使用leaveGroup(InetAddressaddr)方法离开传送组,最后关闭套接字。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序也许你对使用两个字节数组buffer和buffer2感到奇怪,当接收到一个自寻址包后,getData()方法返回一个引用,自寻址包的长度是256个字节,如果要输出所有数据,在输出完实际数据后会有很多空格,这显然是不合理的,所以我们必须去掉这些空格,因此我们创建一个小的字节数组buffer2,buffer2的实际长度就是数据的实际长度,通过调用DatagramPacketsgetLength()方法来得到这个长度。从buffer到buffer2快速复制getLength()的长度的方法是调用System.arraycopy()方法。Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序MCServer的源代码显示了服务程序是怎样工作的。/MCServer.javaimportjava.io.*;.*;classMCServerpublicstaticvoidmain(Stringargs)throwsIOExceptionSystem.out.println(Serverstarting.n);MulticastSockets=newMulticastSocket();InetAddressgroup=InetAddress.getByName(231.0.0.1);Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序bytedummy=newbyte0;DatagramPacketdgp=newDatagramPacket(dummy,0,group,10000);for(inti=0;i30000;i+)bytebuffer=(Videoline+i).getBytes();dgp.setData(buffer);dgp.setLength(buffer.length);s.send(dgp);s.close();Network ProgrammingSoftwareEngineeringSoftwareEngineering5.4.1组播套接字C/S程序MCServer创建了一个MulticastSocket对象,由于他是DatagramPacket对象的一部分,所以他没有绑定端口号,DatagramPacket有多点传送组的IP地址(231.0.0.0),一旦创建DatagramPacket对象,MCServer就进入一个发送30000条的文本的循环中,对文本的每一行均要创建一个字节数组,他们的引用均存储在前面创建的DatagramPacket对象中,通过send()方法,自寻址包发送给所有的组成员。Network ProgrammingSoftwareEngineeringSoftwareEngineering小结小结n数据报套接字是基于UDP协议的,UDP是一种无连接的是一种无连接的C/SC/S通信方式通信方式nUDP不能保证每个数据报是否能够安全、完整地到达目的主机,不能保证数据报的到达时间和到达顺序,但其传输效率比基于Socket套接字的传输效率高。nDatagramPacket表示数据报nDatagramSocket根据该信息把数据报发送到目的地Network ProgrammingSoftwareEngineeringSoftwareEngineering小结小结UDPUDP与与TCPTCP通信的区别通信的区别 n客户机和服务器程序均要建立客户机和服务器程序均要建立DatagramSocketDatagramSocket对象对象;n不会被动地等待建立一个连接的请求;不会被动地等待建立一个连接的请求;n数据报本身含有目标机器的数据报本身含有目标机器的IPIP地址、端口、数据内容。地址、端口、数据内容。Network ProgrammingSoftwareEngineeringSoftwareEngineering课堂练习题课堂练习题1问题:以下哪些叙述是正确的?问题:以下哪些叙述是正确的?选项选项:na)DatagramSocket的的send(DatagramPacket src)方法发送数据报时,如果无法送达接收方,该方法发送数据报时,如果无法送达接收方,该方法会抛出方法会抛出IOException。nb)UDP协议是无连接的协议。协议是无连接的协议。nc)对于用于接收数据的对于用于接收数据的DatagramPacket,如果,如果实际接收到的数据报的长度大于实际接收到的数据报的长度大于DatagramPacket的长度,那么多余的数据就会被丢弃。的长度,那么多余的数据就会被丢弃。nd)DatagramSocket的的getInputStream()方法方法用于获得输入流。用于获得输入流。Network Programming答案答案:b,cSoftwareEngineeringSoftwareEngineering练习题练习题2n问题:以下是问题:以下是DatagramPacket的构造方法,哪些用于发送数据报?的构造方法,哪些用于发送数据报?n选项选项:na)public DatagramPacket(byte data,int length)nb)public DatagramPacket(byte data,int offset,int l
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 压缩资料 > 基础医学


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!