版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章数据报套接字2023/2/21Java网络程序设计本章概述数据报套接字(datagramsocket),又称自寻址套接字。自寻址使用UDP发送寻址信息(从客户程序到服务程序或从服务程序到客户程序),不同的是可以通过自寻址套接字发送多IP信息包,自寻址信息包含在自寻址包中Datagram(数据报)是一种尽力而为(best-effort)的传送数据的方式它只是把数据的目的地记录在数据包(DatagramPacket)中,然后就直接放在网络上,系统不保证数据是否能安全送到,或者什么时候可以送到,也就是说它并不保证传送质量2023/2/22Java网络程序设计本章概述数据报套接字基于的是UDP协议,与TCP保证信息到达信息目的地的方式不同,UDP提供了另外一种方法,如果自寻址信息包没有到达目的地,UDP也不会请求发送者重新发送自寻址包自寻址套接字工作包括下面三个类:DatagramPacket描绘了自寻址包的地址信息DatagramSocket表示客户程序和服务器程序自 寻址套接字MulticastSocket描绘进行多点传送的自寻址套接字这三个类均位于包内2023/2/23Java网络程序设计4.1数据报套接字数据报(Datagram)是网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址信息的消息,它能否到达目的地、到达的时间、到达时内容是否会变化不能准确地知道DatagramSocket本身只是码头,不维护状态,不能产生I/O流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。2023/2/24Java网络程序设计4.1数据报套接字它的通信双方是不需要建立连接的,对于一些不需要很高质量的应用程序来说,数据报通信是一个非常好的选择。在Java的包中有两个类DatagramSocket和DatagramPacket,为应用程序中采用数据报通信方式进行网络通信。2023/2/25Java网络程序设计4.1.1创建DatagramPacket对象使用数据包方式发送信息,首先将数据打包,包中的DategramPacket类用来创建数据包。数据包有两种:一种是用来被发送的数据包,该数据包有要传递到的目的地址;另一种数据包用来接收传递过来的数据包中的数据。2023/2/26Java网络程序设计1.创建的DatagramPacket对象用于接收数据1)publicDatagramPacket(byteibuf[],intilength)
以一个空数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。2)publicDatagramPacket(byteibuf[],intoffset,intilength):
以一个空数组来创建DatagramPacket对象,并指定接收到的数据放入ibuf数组中时从offset开始,最多放ilength个字节。2023/2/27Java网络程序设计1.创建的DatagramPacket对象用于接收数据如:byte[]buffer=newbyte[8912];DatagramPacketdatap=newDatagramPacket(buffer,buffer.length());2023/2/28Java网络程序设计2.创建的DatagramPacket对象用于发送数据1)publicDatagramPacket(bytibuf[],intilength,InetAddrssiaddr,intport)以一个包含数据的数组来创建DatagramPacket对象,创建该DatagramPacket时还指定了IP地址和端口号——这就决定了该数据报的目的地址。2)publicDatagramPacket(bytibuf[],intoffset,intilength,InetAddrssiaddr,intport)创建一个用于发送的DatagramPacket对象,也多指定了一个offset参数。
2023/2/29Java网络程序设计2.创建的DatagramPacket对象用于发送数据如:Strings=newString(“javanetworking”);byte[]data=s.getbytes();intport=1024;try{InetAddressineta=InetAddress.getByName(“4”);DatagramPacketdatap=newDatagramPacket(data,data.length(),ineta,port);}catch(IOExceptioe){}2023/2/210Java网络程序设计4.1.1创建DatagramPacket对象当服务器(也可以是客户端)接收到一个DategramPacket对象后,如果想向该数据报的发送者“反馈”一些信息,但由于UDP是面向非连接的,所以接收者并不知道每个数据报由谁发送过来,但程序可以调用DategramPacket的方法来获取发送者的IP地址和端口号。下面我们来看DategramPacket的常用方法。2023/2/211Java网络程序设计4.1.2DatagramPacket的常用方法(1)publicbyte[]getData()
返回一个字节数组,其中是数据包的数据。如果想把字节数组转换成别的类型就要进行转化。(2)publicInetAddressgetAddress()
返回某台机器的IP地址,当程序准备发送数据报时,该方法返回此数据报的目标机器的IP地址;当程序刚刚接收到一个数据报时,该方法返回该数据报的发送主机的IP地址。(3)publicbyte[]getLength()
获得数据报中数据的字节数。2023/2/212Java网络程序设计4.1.2DatagramPacket的常用方法(4)pubicintgetPort()
返回某台机器的端口号,当程序员准备发送此数据报时,该方法返回此数据报的目标机器的IP地址;当程序员刚刚接收到一个数据报时主,该方法返回数据报的发送主机的IP地址。(5)pubicSocketAddressgetSocketAddress()
返回要将此包发送到的或此数据报的远程主机的SocketAddress(通常为IP地址+端口号)
(6)pubicintgetOffset()
返回将发送或接收的数据的偏移量2023/2/213Java网络程序设计4.1.2DatagramPacket的常用方法设置DatagramPacket对象属性的方法如下:(1)publicvoidsetAddress(InetAddressiaddr)
设置要将此数据报发往的那台机器的IP地址。(2)publicvoidsetData(byte[]buf)
为此包设置数据缓冲区。(3)publicvoidsetData(byte[]buf,intoffset,intlength)
为此包设置数据缓冲区。(4)publicvoidsetLength(intlength)
为此包设置长度。2023/2/214Java网络程序设计4.1.2DatagramPacket的常用方法(5)publicvoidsetPot(intport)
设置要将此数据报发往的远程主机上的端口号。(6)publicvoidsetSocketAddress(SocketAddressaddress)
为此要将地数据报发往的远程主机的SocketAddress(通常为IP地址+端口号)。2023/2/215Java网络程序设计4.1.3创建DatagramSocket对象发送和接收数据包还需要发送和接收数据包的数据报套接字,即DatagramSocket对象,DatagramSocket在本地机器端口监听是否有数据到达或者将数据包发送出去。(1)publicDatagramSocket()
用本地机器上任何一个可用的端口创建一个数据报套接字,这个端口号是由系统随机产生的。这种构造方法没有指定端口号,可以用在客户端。如果构造不成功则触发SocketException异常。2023/2/216Java网络程序设计4.1.3创建DatagramSocket对象(2)publicDatagramSocket(intport)
用一个指定的端口号port创建一个数据报套接字。当不能创建数据报套接字时就抛出SocketException异常,其原因是指定的端口已被占用或者是试图连接低于1024的端口,但是又没有具备权限。(3)publicDatagramSocket(intport,InetAddressladdr)
创建一个DatagramSocket对象,并将该对象绑定到指定的IP地址和端口。2023/2/217Java网络程序设计4.1.4DatagramSocket的常用方法一旦得到了DatagramSocket对象之后,就可以通过如下两个方法来接收和发送数据:(1)publicvoid
receive(DatagramPacketp)从该DatagramSocket中接收数据报。(2)publicvoidsend(DatagramPacketp)以该DatagramSocket对象向外发送数据报。2023/2/218Java网络程序设计4.1.4DatagramSocket的常用方法从上面两个方法可以看出,使用DatagramSocket发送数据报时,DatagramSocket并不知道将该数据报发送到哪里,而是由DatagramPacket自身决定数据报的目的地。就像码头并不知道每个集装箱的目的地,码头只是将这些集装箱发送出去,而集装箱本身包含了该集装箱的目的地。除此之外,DatagramSocket还有一些常用方法:(3)publicInetAddressgetLocalAddress()获取数据报套接字绑定的本地IP地址。(4)publicintgetLocalPort()返回数据报套接字绑定的本地主机上的端口。2023/2/219Java网络程序设计4.1.4DatagramSocket的常用方法(5)publicSocketAddressgetLocalSocketAddress()返回一个SocketAddress对象,它包含此数据报套接字绑定的IP地址和端口号。2023/2/220Java网络程序设计4.1.5数据报套接字编程(1)首先要建立数据报通信的Socket,我们可以通过创建一个DatagramSocket对象实现它,在Java中DatagramSocket类有如下两种构造方法:
publicDatagramSocket()构造一个数据报socket,并使其与本地主机任一可用的端口连接。若打不开socket则抛出SocketException异常。publicDatagramSocket(intport)构造一个数据报socket,并使其与本地主机指定的端口连接。若打不开socket或socket无法与指定的端口连接则抛出SocketException异常。2023/2/221Java网络程序设计4.1.5数据报套接字编程(2)创建一个数据报文包,用来实现无连接的包传送服务。每个数据报文包用DatagramPacket类创建,DatagramPacket对象封装了数据报包数据、包长度、目标地址和目标端口。客户端要发送数据报文包,要调用DatagramPacket类以如下形式的构造函数创建DatagramPacket对象,将要发送的数据和包文目的地址信息放入对象之中。DatagramPacket(bytebufferedarray[],intlength,InetAddressaddress,intport)即构造一个包长度为length的包传送到指定主机指定端口号上的数据报文包,参数length必须小于等于bufferedarry.length。2023/2/222Java网络程序设计4.1.5数据报套接字编程DatagramPacket类提供了4个类获取信息:publicbyte[]getData()返回一个字节数组,包含收到或要发送的数据报中的数据。
publicintgetLength()返回发送或接收到的数据的长度。
publicInetAddressgetAddress()返回一个发送或接收此数据报包文的机器的IP地址。publicintgetPort()返回发送或接收数据报的远程主机的端口号。2023/2/223Java网络程序设计4.1.5数据报套接字编程(3)创建完DatagramSocket和DatagramPacket对象,就可以发送数据报文包了。发送是通过调用DatagramSocket对象的send方法实现,它需要以DatagramPacket对象为参数,将刚才封装进DatagramPacket对象中的数据组成数据报发出。2023/2/224Java网络程序设计4.1.5数据报套接字编程(4)也可以接收数据报文包。
为了接收从服务器返回的结果数据报文包,我们需要创建一个新的DatagramPacket对象,这就需要用到DatagramPacket的另一种构造方式DatagramPacket(bytebufferedarray[],intlength),即只需指明存放接收的数据报的缓冲区和长度。2023/2/225Java网络程序设计4.1.5数据报套接字编程调用DatagramSocket对象的receive()方法完成接收数据报的工作,此时需要将上面创建的DatagramPacket对象作为参数,该方法会一直阻塞直到收到一个数据报文包,此时DatagramPacket的缓冲区中包含的就是接收到的数据,数据报文包中也包含发送者的IP地址,发送者机器上的端口号等信息。2023/2/226Java网络程序设计4.1.5数据报套接字编程(5)处理接收缓冲区内的数据,获取服务结果。(6)当通信完成后,可以使用DatagramSocket对象的close()方法关闭数据报通信Socket。当然,Java会自动关闭Socket,释放DatagramSocket和DatagramPacket所占用的资源。但是作为一种良好的编程习惯,还是要显式地予以关闭。数据报套接字通信的流程如下图所示:2023/2/227Java网络程序设计接收端(Receiver)DatagramSocket(intport)DatagramPacket(byte[]buf,intlength)DatagramSocket.receive(DatagramPacketp)DatagramSocket.close()发送端(Sender)DatagramSocket()DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)DatagramSocket.send(DatagramPacketp)DatagramSocket.close()2023/2/228Java网络程序设计楚雄师范学院计算机科学系java程序设计课程29/1389.2数据报程序设计2023/2/229Java网络程序设计4.2DatagramSocket编程示例4.2.1利用数据报套接字查询端口占用情况用DatagramSocket(intport)构造方法创建一个数据报套接字时,如果指定端口已被其他服务占用,则不能创建数据报套接字,且会抛出SocketException异常,我们可以利用这个异常探查本地机的端口有没有服务。程序如下:2023/2/230Java网络程序设计4.2.1利用数据报套接字查询端口占用情况.DatagramSocket;.SocketException;publicclassUDPScan{ publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub for(intport=1024;port<=65535;port++){ try{ DatagramSocketserver=newDatagramSocket(port); server.close();
}2023/2/231Java网络程序设计4.2.1利用数据报套接字查询端口占用情况
}catch(SocketExceptione){ System.out.println("thereisaserverinport"+port+"."); } } }}2023/2/232Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器importjava.io.IOException;.DatagramPacket;.DatagramSocket;.SocketException;publicclassUDPServer{publicstaticvoidmain(String[]args){ try{ DatagramSocketreceiveSocket=newDatagramSocket(5000); bytebuf[]=newbyte[1000]; DatagramPacketreceivePacket=newDatagramPacket(buf,buf.length); System.out.println("开始接收包");2023/2/233Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器 while(true){receiveSocket.receive(receivePacket); Stringname=receivePacket.getAddress().toString(); System.out.println("\n来自主机:"+name+"\n端口:"+receivePacket.getPort()); Strings=newString(receivePacket.getData(),0,receivePacket.getLength()); System.out.println("收到的数据:"+s); } }catch(SocketExceptione){ e.printStackTrace(); System.exit(1); }2023/2/234Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器 catch(IOExceptione){ System.out.println("网络通信出现错误,问题在"+e.toString());}}}2023/2/235Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器importjava.io.IOException;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;publicclassUDPClient{ publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub2023/2/236Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器 try{ DatagramSocketsendSocket=newDatagramSocket(3456); Stringstring="你好!这里是客户端"; byte[]databyte=newbyte[100]; databyte=string.getBytes(); DatagramPacketsendPacket=newDatagramPacket(databyte,string.length(),InetAddress.getByName(""),5000);2023/2/237Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器 sendSocket.send(sendPacket); System.out.println("发送数据:你好!这里是客户端"); }catch(SocketExceptione){ System.out.println("不能打开数据报Socket,或数据报Socket无法与指定端口连接!"); }2023/2/238Java网络程序设计4.2.2利用数据报进行通信:创建UDP服务器catch(IOExceptione){ System.out.println("网络通信出现错误,问题出在"+e.toString()); } }}2023/2/239Java网络程序设计楚雄师范学院计算机科学系java程序设计课程40/1384.2.3使用数据报套接字完成前章计算面积例客户/服务器举例。2023/2/240Java网络程序设计楚雄师范学院计算机科学系java程序设计课程41/138
importjava.io.*;.*;importjava.util.*;importjava.awt.*;importjavax.swing.*;2023/2/241Java网络程序设计楚雄师范学院计算机科学系java程序设计课程42/138publicclassDatagramServerextendsJFrame{//TextareafordisplayingcontentsprivateJTextAreajta=newJTextArea();//发送和接收数据报分组的字节数组privatebyte[]buf=newbyte[256];publicstaticvoidmain(String[]args){newDatagramServer();}2023/2/242Java网络程序设计楚雄师范学院计算机科学系java程序设计课程43/138publicDatagramServer(){//PlacetextareaontheframesetLayout(newBorderLayout());add(newJScrollPane(jta),BorderLayout.CENTER);setTitle("DatagramServer");setSize(500,300);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);2023/2/243Java网络程序设计楚雄师范学院计算机科学系java程序设计课程44/138
try{//CreateaserversocketDatagramSocketsocket=newDatagramSocket(8000);jta.append("Serverstartedat"+newDate()+'\n');//CreateapacketforreceivingdataDatagramPacketreceivePacket=newDatagramPacket(buf,buf.length);2023/2/244Java网络程序设计楚雄师范学院计算机科学系java程序设计课程45/138//CreateapacketforsendingdataDatagramPacketsendPacket=newDatagramPacket(buf,buf.length);while(true){//初始化缓冲区eachiterationArrays.fill(buf,(byte)0);2023/2/245Java网络程序设计楚雄师范学院计算机科学系java程序设计课程46/138//通过包接收半径socket.receive(receivePacket);jta.append("Theclienthostnameis"+receivePacket.getAddress().getHostName()+"andportnumberis"+receivePacket.getPort()+'\n');jta.append("Radiusreceivedfromclientis"+newString(buf).trim()+'\n');//Computearea2023/2/246Java网络程序设计楚雄师范学院计算机科学系java程序设计课程47/138//Computeareadoubleradius=Double.parseDouble(newString(buf).trim());doublearea=radius*radius*Math.PI;jta.append("Areais"+area+'\n');//发送面积sendPacket.setAddress(receivePacket.getAddress());//设置客户地址sendPacket.setPort(receivePacket.getPort());//设置客户端口2023/2/247Java网络程序设计楚雄师范学院计算机科学系java程序设计课程48/138sendPacket.setData(newDouble(area).toString().getBytes());socket.send(sendPacket);//发送}
}
catch(IOExceptionex){ex.printStackTrace();
}}}2023/2/248Java网络程序设计楚雄师范学院计算机科学系java程序设计课程49/138importjava.io.*;.*;importjava.util.*;importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;publicclassDatagramClientextendsJFrame{//TextfieldforreceivingradiusprivateJTextFieldjtf=newJTextField();2023/2/249Java网络程序设计楚雄师范学院计算机科学系java程序设计课程50/138//TextareatodisplaycontentsprivateJTextAreajta=newJTextArea();//DatagramsocketprivateDatagramSocketsocket;//Thebytearrayforsendingandreceivingdatagrampacketsprivatebyte[]buf=newbyte[256];2023/2/250Java网络程序设计楚雄师范学院计算机科学系java程序设计课程51/138//ServerInetAddressprivateInetAddressaddress;//ThepacketsenttotheserverprivateDatagramPacketsendPacket;//ThepacketreceivedfromtheserverprivateDatagramPacketreceivePacket;publicstaticvoidmain(String[]args){newDatagramClient();}2023/2/251Java网络程序设计楚雄师范学院计算机科学系java程序设计课程52/138publicDatagramClient(){//包含标签和文本的面板JPanelp=newJPanel();p.setLayout(newBorderLayout());p.add(newJLabel("Enterradius"),BorderLayout.WEST);p.add(jtf,BorderLayout.CENTER);jtf.setHorizontalAlignment(JTextField.RIGHT);2023/2/252Java网络程序设计楚雄师范学院计算机科学系java程序设计课程53/138setLayout(newBorderLayout());add(p,BorderLayout.NORTH);add(newJScrollPane(jta),BorderLayout.CENTER);jtf.addActionListener(newButtonListener());//RegisterlistenersetTitle("DatagramClient");setSize(500,300);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);2023/2/253Java网络程序设计楚雄师范学院计算机科学系java程序设计课程54/138setVisible(true);
try{//getadatagramsocketsocket=newDatagramSocket();address=InetAddress.getByName("localhost");sendPacket=newDatagramPacket(buf,buf.length,address,8000);receivePacket=newDatagramPacket(buf,buf.length);
}2023/2/254Java网络程序设计楚雄师范学院计算机科学系java程序设计课程55/138catch(IOExceptionex){ex.printStackTrace();
}}privateclassButtonListenerimplementsActionListener{publicvoidactionPerformed(ActionEvente){
try{//初始化缓冲区eachiterationArrays.fill(buf,(byte)0);2023/2/255Java网络程序设计楚雄师范学院计算机科学系java程序设计课程56/138//发送半径给予服务器sendPacket.setData(jtf.getText().trim().getBytes());socket.send(sendPacket);//从服务器接收面积socket.receive(receivePacket);//显示2023/2/256Java网络程序设计楚雄师范学院计算机科学系java程序设计课程57/138jta.append("Radiusis"+jtf.getText().trim()+"\n");jta.append("Areareceivedfromtheserveris"+Double.parseDouble(newString(buf).trim())+'\n');
}
catch(IOExceptionex){ex.printStackTrace();
}}}}2023/2/257Java网络程序设计楚雄师范学院计算机科学系java程序设计课程58/1384.2.4使用数据报套接字编写聊天软件客户/服务器举例。2023/2/258Java网络程序设计楚雄师范学院计算机科学系java程序设计课程59/1384.2.4使用数据报套接字编写聊天软件importjava.awt.BorderLayout;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.IOException;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;2023/2/259Java网络程序设计楚雄师范学院计算机科学系java程序设计课程60/1384.2.4使用数据报套接字编写聊天软件.UnknownHostException;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassUDPChatimplementsActionListener,Runnable{2023/2/260Java网络程序设计楚雄师范学院计算机科学系java程序设计课程61/1384.2.4使用数据报套接字编写聊天软件 JTextAreashowArea; JLabellbl1,lbl2,lbl3; JTextFieldmsgText,sendPortText,receivePortText,IPAddressText; JFramemainJframe; JButtonsendBtn,startBtn; JScrollPaneJSPane; JPanelpane1,pane2; Containercon; Threadthread=null;2023/2/261Java网络程序设计楚雄师范学院计算机科学系java程序设计课程62/1384.2.4使用数据报套接字编写聊天软件 DatagramPacketsendPacket,receivePacket; DatagramSocketsendSocket,receiveSocket; privateInetAddresssendIP; privateintsendPort,receivePort; privatebyteinBuf[],outBuf[]; publicfinalintBUFSIZE=1024; publicUDPChat(){ mainJframe=newJFrame("聊天--UDP协议"); con=mainJframe.getContentPane(); showArea=newJTextArea(); showArea.setEditable(false);2023/2/262Java网络程序设计楚雄师范学院计算机科学系java程序设计课程63/1384.2.4使用数据报套接字编写聊天软件 showArea.setLineWrap(true); lbl1=newJLabel("接收端口:"); lbl2=newJLabel("发送端口:"); lbl3=newJLabel("对方的地址:"); sendPortText=newJTextField(); sendPortText.setColumns(5); receivePortText=newJTextField(); receivePortText.setColumns(5); IPAddressText=newJTextField(); IPAddressText.setColumns(5); startBtn=newJButton("开始"); startBtn.addActionListener(this);2023/2/263Java网络程序设计楚雄师范学院计算机科学系java程序设计课程64/1384.2.4使用数据报套接字编写聊天软件 pane1=newJPanel(); pane1.setLayout(newFlowLayout()); pane1.add(lbl1); pane1.add(receivePortText); pane1.add(lbl2); pane1.add(sendPortText); pane1.add(lbl3); pane1.add(IPAddressText); pane1.add(startBtn); JSPane=newJScrollPane(showArea); msgText=newJTextField(); msgText.setColumns(40);2023/2/264Java网络程序设计楚雄师范学院计算机科学系java程序设计课程65/1384.2.4使用数据报套接字编写聊天软件 msgText.setEditable(false); msgText.addActionListener(this); sendBtn=newJButton("发送"); sendBtn.setEnabled(false); sendBtn.addActionListener(this); pane2=newJPanel(); pane2.setLayout(newFlowLayout()); pane2.add(msgText); pane2.add(sendBtn); con.add(pane1,BorderLayout.NORTH); con.add(JSPane,BorderLayout.CENTER);2023/2/265Java网络程序设计楚雄师范学院计算机科学系java程序设计课程66/1384.2.4使用数据报套接字编写聊天软件con.add(pane2,BorderLayout.SOUTH);mainJframe.setSize(600,400);mainJframe.setVisible(true);mainJframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub newUDPChat(); }2023/2/266Java网络程序设计楚雄师范学院计算机科学系java程序设计课程67/1384.2.4使用数据报套接字编写聊天软件publicvoidactionPerformed(ActionEventarg0){//TODOAuto-generatedmethodstub try{if(arg0.getSource()==startBtn){ inBuf=newbyte[BUFSIZE]; sendPort=Integer.parseInt(sendPortText.getText()); sendIP=InetAddress.getByName(IPAddressText.getText()); sendSocket=newDatagramSocket(); receivePort=Integer.parseInt(receivePortText.getText());2023/2/267Java网络程序设计楚雄师范学院计算机科学系java程序设计课程68/1384.2.4使用数据报套接字编写聊天软件//创建接收数据包receivePacket=newDatagramPacket(inBuf,BUFSIZE);//指定接收数据的端口receiveSocket=newDatagramSocket(receivePort);//创建线程准备接收对方的消息thread=newThread(this);thread.setPriority(Thread.MIN_PRIORITY);thread.start();startBtn.setEnabled(false);sendBtn.setEnabled(true);2023/2/268Java网络程序设计楚雄师范学院计算机科学系java程序设计课程69/1384.2.4使用数据报套接字编写聊天软件msgText.setEditable(true);
}else{ outBuf=msgText.getText().getBytes(); //组装要发送的数据包
sendPacket=newDatagramPacket(outBuf,outBuf.length,sendIP,sendPort); //发送数据sendSocket.send(sendPacket); showArea.append("我说:"+msgText.getText()+"\n"); msgText.setText(null);}2023/2/269Java网络程序设计楚雄师范学院计算机科学系java程序设计课程70/1384.2.4使用数据报套接字编写聊天软件}catch(UnknownHostExceptione){ showArea.append("无法连接到指定\n");}catch(SocketExceptione){ showArea.append("无法打开指定端口\n");}catch(IOExceptione){ showArea.append("发送数据失败\n");}}publicvoidrun(){//TODOAuto-generatedmethodstubStringmsgstr;2023/2/270Java网络程序设计楚雄师范学院计算机科学系java程序设计课程71/1384.2.4使用数据报套接字编写聊天软件while(true){ try{ receiveSocket.receive(receivePacket); msgstr=newString(receivePacket.getData(),0,receivePacket.getLength()); showArea.append("对方说:"+msgstr+"\n"); }catch(IOExceptione){ showArea.append("接收数据出错\n"); }}}}2023/2/271Java网络程序设计2023/2/272Java网络程序设计4.3组播套接字如果服务器程序要将同一信息发送给多个客户端,那么服务器程序和客户程序可以利用多点传送(multicasting)方式进行通信。2023/2/273Java网络程序设计4.3组播套接字多点传送就是服务程序对专用的多点传送组的IP地址和端口发送一系列自寻址数据包,通过加入操作IP地址被多点传送Socket注册,通过这个点客户程序可以接收发送给组的自寻址包(同样客户程序也可以给这个组发送自寻址包),一旦客户程序读完所有要读的自寻址数据包,那么可以通过离开组操作离开多点传送组。2023/2/274Java网络程序设计组播套接字DatagramSocket只允许数据报发送给指定的目标地址,而MulticastSocket可以将数据报以广播方式发送到数量不等的多个客户端。若要使用多点广播时,则需要让一个数据报标有一组目标主机地址,当数据报发出后,整个组的所有主机都能收到该数据报。IP多点广播(或多点传送)实现了将单一信息发送到多个接收者的广播,其思想是设置一组特殊网络地址作为多点广播地址,每一个多点广播地址都被看作一个组,当客户端需要发送、接收广播信息时,加入到该组即可。IP协议为多点广播2023/2/275Java网络程序设计组播套接字提供了这批特殊的IP地址,这些IP地址的范围是---55。其中~55为预留的组播地址(永久组地址),地址保留不做分配,其它地址供路由协议使用;~55是公用组播地址,可以用于Internet;~55为用户可用的组播地址(临时组地址),全网范围内有效;~55为本地管理组播地址,仅在特定的本地范围内有效。2023/2/276Java网络程序设计组播套接字组播地址列表如下:基准地址(保留)所有主机的地址(包括所有路由器地址)所有组播路由器的地址不分配dvmrp路由器所有ospf路由器ospfDR/BDRst路由器st主机2023/2/277Java网络程序设计组播套接字组播地址列表如下:基准地址(保留)所有主机的地址(包括所有路由器地址)所有组播路由器的地址不分配dvmrp路由器其中DVMRP(DistanceVectorMulticastRoutingProtocol)的意思是:2023/2/278Java网络程序设计组播套接字距离向量多播选路协议,由单播路由协议RIP扩展而来,两者都使用距离向量算法得到网络的拓扑信息,不同之处在于RIP根据路由表前向转发数据,而DVMRP则是基于RPF。为了使新加入的组播成员能及时收到组播数据,DVMPR采用定时发送数据包给所有的LAN的方法,导致大量路由控制数据包的扩散,限制了网络规模的扩大。另一方面,DVMRP使用上限为32跳跳数作为计量尺度,这对网络规模也是一个限制。2023/2/279Java网络程序设计组播套接字rip-2路由器0Eigrp路由器1活动代理2dhcp服务器/中继代理3所有pim路由器4rsvp封装5所有cbt路由器6指定sbm7所有sbms8vrrp2023/2/280Java网络程序设计组播套接字
以太网传输单播ip报文的时候,目的mac地址使用的是接收者的mac地址。但是在传输组播报文时,传输目的不再是一个具体的接收者,而是一个成员不确定的组,所以使用的是组播mac地址。组播mac地址是和组播ip地址对应的。iana(internetassignednumberauthority)规定,组播mac地址的高24bit为0x01005e,mac地址的低23bit为组播ip地址的低23bit。由于ip组播地址的后28位中只有23位被映射到mac地址,这样就会有32个ip组播地址映射到同一mac地址上。。2023/2/281Java网络程序设计组播套接字网络应用程序接口通过MulticastSocket类及一些辅助类支持多点传送,当一个客户程序要加入多点传送组时,就创建一个MulticastSocket对象。MulticastSocket(intport)构造函数允许应用程序指定端口(通过port参数)接收自寻址包,端口必须与服务程序的端口号相匹配,要加入多点传送组,客户程序调用两个joinGroup()方法中的一个;同样要离开传送组也需要调用两个leaveGroup()方法中的一个。2023/2/282Java网络程序设计组播套接字Java的MulticastSocket类是实施IP多点传送网络特征的关键,它允许我们使用多点传送IP,发送或接收UDP数据报MulticastSocket是一个具有更多功能的DatagramSocket类,它能将多点传送主机结合成组。2023/2/283Java网络程序设计4.3.1创建MulticastSocket对象在Java中,可以用.MulticastSocket类组播数据。组播套接字是DatagramSocket的子类,定义如下:publicclassMulticastSocketextendsDatagramSocket构造方法有:(1)publicMulticastSocket():使用本机默认地址、随机端口来创建一个MulticastSocket对象。2023/2/284Java网络程序设计4.3.1创建MulticastSocket对象(2)
publicMulticastSocket(intport):
使用本机默认地址、指定端口创建一MulticastSocket对象。(3)
publicMulticastSocket(SocketAddrtessbindaddr):
使用本机指定的IP地址、指定端口来创建一MulticastSocket对象。如果创建仅用于发送数据报的MulticastSocket对象,则使用默认地址、随机端口即可。但如果创建接收用的MulticastSocket对象,则该对象必须具有指定端口,否则发送方无法确定发送数据报的目标端口。2023/2/285Java网络程序设计4.3.2MulticastSocket的常用方法常用的方法如下:
(1)publicvoidjoinGroup(InetAddressaddress)throwsIOException:建立了MulticastSocket对象后,为了发送或者接收组播包,必须用joinGroup方法加入一个组播组。若加入的不是组播地址将触发IOException异常。2023/2/286Java网络程序设计4.3.2MulticastSocket的常用方法(2)publicvoidleaveGroup(InetAddressaddress)throwsIOException:
如果不想接收组播包了,就调用leaveGroup方法。程序就发信息到组播路由器,通知它向此用户发送数据。若想离开的地址不是组播地址就触发IOException异常。2023/2/287Java网络程序设计4.3.2MulticastSocket的常用方法(3)publicvoidsend(DatagramPacketpacket,byte,ttl)throwsIOExceptin:
发送组播包的方法与DatagramSocket发送数据相似。其中ttl是生存时间,大小在0~255之间。(4)publicvoidreceive(DatagramPacketp):
与DatagramSocket的接收方法没有差别。2023/2/288Java网络程序设计4.3.2MulticastSocket的常用方法(5)publicvoidsetTimeToLive(intttl)throwsIOException:
设置套接字发出的组播包中的默认ttl数值。
(6)publicintgetTimeToLive()throwsIOException:
返回ttl数值。2023/2/289Java网络程序设计4.3.3组播套接字编程使用组播套接字发送数据的过程:(1)调用MulticastSocket()创建一个组播套接字。(2)调用MulticastSocket类的joinGroup()方法加入一个组播组中。(3)创建DatagramPacket数据报。(4)调用MulticastSocket类的send()方法发送组播包。(5)调用MulticastSocket类的leaveGroup()方法离开该组播组。(6)关闭组播套接字。发送一个组播包的代码如下:2023/2/290Java网络程序设计4.3.3组播套接字编程InetAddressaddress=InetAddress.getByName(“”);byte[]data=“multicastsocketprogramming”.getBytes();intport=5000;DatagramPacketdatap=newDatagramPacket(data,data.length(),address,port);MulticastSocketmuls=newMulticastSocket();muls.send(datap);2023/2/291Java网络程序设计4.3.3组播套接字编程使用组播套接字接收数据的过程:(1)调用MulticastSocket(intport)创建一个组播套接字,并绑定到指定端口上。(2)调用MulticastSocket类的joinGroup()方法加入一个组播组中。(3)创建DatagramPacket数据报。(4)调用MulticastSocket类的receive()方法接收组播数据报。(5)调用MulticastSocket类的leaveGroup()方法离开该组播组。(6)关闭组播套接字MulticastSocket。2023/2/292Java网络程序设计4.3.4组播套接字编程例子例1:组播窃听器。.*;importjava.io.*;importjavax.swing.JOptionPane;publicclassMulticastSniffer{publicstaticvoidmain(String[]args){InetAddressgroup=null;intport=0;StringIPName,portName;2023/2/293Java网络程序设计4.3.4组播套接字编程例子//readtheaddressIPName=JOptionPane.showInputDialog("请输入组播名或IP地址");portName=JOptionPane.showInputDialog("请输入端口");try{group=InetAddress.getByName(IPName);port=Integer.parseInt(portName);}//endtrycatch(Exceptionex){System.err.println(“出错");System.exit(1);}2023/2/294Java网络程序设计4.3.4组播套接字编程例子MulticastSocketms=null;try{ms=newMulticastSocket(port);ms.joinGroup(group);byte[]buffer=newbyte[8192];while(true){DatagramPacketdp=newDatagramPacket(buffer,buffer.length);ms.receive(dp);Strings=newString(dp.getData());System.out.println(s);}2023/2/295Java网络程序设计4.3.4组播套接字编程例子}catch(IOExceptionex){System.err.println(ex);}finally{if(ms!=null){try{ms.leaveGroup(group);ms
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 护理课件老年人尿路感染护理
- 《证券行情指标分析》课件
- 《教材循环利用》课件
- 初中体育与健康教学参考计划5篇
- 《软件无线电原理与技术》课件-第3章
- 2024-2025学年年八年级数学人教版下册专题整合复习卷第14章 一次函数单元复习测试卷(含答案)
- 加油站安全设备管理培训教材
- 《第一章》课件-第六章:无人船
- 安全生产责任的归属与分工
- 2025年海南货运从业资格证考试模拟试题答案
- 部编版五年级语文上册期末试卷(含答案)-
- 关键岗位人员安全职责的明确与落实策略探讨
- 医用氧气安全培训课件
- 物资、百货、五金采购 投标方案(技术方案)
- MOOC 国际金融-天津财经大学 中国大学慕课答案
- 中学水电维修工工作职责(3篇)
- 2023-2024学年河南省开封市祥符区六年级下学期小升初招生语文试卷含答案
- 婚礼准备流程
- 2023-2024年人教版七年级上册数学期末试题(含简单答案)
- 人教版六年级上册数学《圆》大单元作业设计
- 【培训课件】proe工程图培训
评论
0/150
提交评论