JAVA基于UDP的多点广播数据报技术的一个实现例子
This is a UDP network program. The following presents a multicast datagram program, which is actually a new technology. The multicast datagram socket class is useful for sending and receiving IP multicast packets. A MulticastSocket is a (UDP) DatagramSocket, with additional capabilities for joining "groups" of other multicast hosts on the internet.
A multicast group is specified by a class D IP address and by a standard UDP port number. Class D IP addresses are in the range 224.0.0.0 to 239.255.255.255, inclusive. The address 224.0.0.0 is reserved and should not be used.
One would join a multicast group by first creating a MulticastSocket with the desired port, then invoking the joinGroup(InetAddress groupAddr) method:
// join a Multicast group and send the group salutations
...
String msg = "Hello";
InetAddress group = InetAddress.getByName("228.5.6.7");
MulticastSocket s = new MulticastSocket(6789);
s.joinGroup(group);
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(), group, 6789);
s.send(hi);
// get their responses! Normally in another computer(host) who joins in the specific group.
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
s.receive(recv);
...
// OK, I'm done talking - leave the group...
s.leaveGroup(group);
When one sends a message to a multicast group, all subscribing recipients to that host and port receive the message (within the time-to-live range of the packet, see below). The socket needn't be a member of the multicast group to send messages to it.
When a socket subscribes to a multicast group/port, it receives datagrams sent by other hosts to the group/port, as do all other members of the group and port. A socket relinquishes membership in a group by the leaveGroup(InetAddress addr) method.
By the way, I'd like to talk about a bit the Datagram communication which is based on UDP, contrast to the TCP based program.
For UDP based program:
In the send part, one uses new DatagramSocket()
to create a socket, not binding a port, which instead will be designated by the system automatically. Then, we can usenew DatagramPacket(data, data.length, InetAddress, port)
to create
a packet. Finally, invokesocket.send(packet)
to complete the send part operation.
In the receive part, one uses new DatagramSocket(port)
to create a socket, note that we have to bind a port to match the one in the coming packet. Then, we can usenew DatagramPacket(dataBuf, dataBuf.length)
to create a packet to
hold the incoming packet. Finally, invokesocket.receive(packet)
to finalize the receive part operation.
For TCP based program:
There is a clear distinction between the client part and the server part. I mean that in the server part program, there is a socket called ServerScoket, which can be created bynew ServerSocket(port)
, and wait for its client's request, once it
happens, it creates a socket object automatically to connect the client socket by:
Socket socket=serverSocket.accept()
In which serverSocket
is a citation of the object to the class ServerSocket. One should note that the accept() method will block the executing thread until the reception of the client's request. If there is no request received, but the accept()
is not blocked, there must be a bug in the program. Normally, this is due to the usage of a port that is occupied at the same time by another program. It is to say that ServerSocket is not successfully binded.
In the client part programming, we should create a socket like this: new Socket(InetAddress server, port)
to establish a connection to the server.
Both the server socket object and the client socket object can call the method getOutputStream() and getInputStream(). So these sockets use them to communicate, instead of send() and receive() for the DatagramSocket.
You might think that why there are so detailed procedures to follow. Simply, the response is that it is described and imposed in the API (Application Programming Interface) by Java SUN. We can not create but obey it.
- Author:
HAN
package com.han; import java.net.*; /** * This is a UDP network program. * The following presents a multicast datagram program, * which is actually a new technology. * * The multicast datagram socket class is useful for sending and receiving * IP multicast packets. A MulticastSocket is a (UDP) DatagramSocket, * with additional capabilities for joining "groups" of other multicast hosts on the internet. * <p> * A multicast group is specified by a class D IP address and by a standard UDP port number. * Class D IP addresses are in the range 224.0.0.0 to 239.255.255.255, inclusive. * The address 224.0.0.0 is reserved and should not be used. * <p> * One would join a multicast group by first creating a MulticastSocket with the desired port, * then invoking the joinGroup(InetAddress groupAddr) method: * <p> * <code> * // join a Multicast group and send the group salutations<p> * ...<p> * String msg = "Hello";<p> * InetAddress group = InetAddress.getByName("228.5.6.7");<p> * MulticastSocket s = new MulticastSocket(6789);<p> * s.joinGroup(group);<p> * DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(), group, 6789);<p> * s.send(hi);<p> * // get their responses! Normally in another computer(host) who joins in the specific group.<p> * byte[] buf = new byte[1000];<p> * DatagramPacket recv = new DatagramPacket(buf, buf.length);<p> * s.receive(recv); <p> * ...<p> * // OK, I'm done talking - leave the group...<p> * s.leaveGroup(group);<p> </code> * When one sends a message to a multicast group, all subscribing recipients to that host * and port receive the message (within the time-to-live range of the packet, see below). * The socket needn't be a member of the multicast group to send messages to it. * <p> * When a socket subscribes to a multicast group/port, * it receives datagrams sent by other hosts to the group/port, * as do all other members of the group and port. * A socket relinquishes membership in a group by the leaveGroup(InetAddress addr) method. * * <p> * By the way, I'd like to talk about a bit the Datagram communication which based on UDP, * contrast to the TCP based program. * <p> * For UDP based program: * <p> * In the send part, one uses <code>new DatagramSocket()</code> to create a socket, not binding * a port, which instead will be designated by the system automatically. Then, we can use <code> * new DatagramPacket(data, data.length, InetAddress, port)</code> to create a packet. Finally, * invoke <code>socket.send(packet)</code> to complete the send part operation. * <p> * In the receive part, one uses <code>new DatagramSocket(port)</code> to create a socket, * note that we have to bind a port to match the one in the coming packet. * Then, we can use <code>new DatagramPacket(dataBuf, dataBuf.length)</code> to create a packet * to stock the coming packet. Finally, invoke <code>socket.receive(packet)</code> * to finalize the receive part operation. * * <p> * For TCP based program: * <p> * There is a clear distinction between the client part and the server part. I mean that in the * server part program, there is a socket called ServerScoket, which can be created by <code> * new ServerSocket(port)</code>, and wait for its client's request, once it happens, it creates a * socket object automatically to connect the client socket by: <pre><code> * Socket socket=serverSocket.accept()</code></pre> * In which <code>serverSocket</code> is a citation of the object to the class ServerSocket. * One should note that the accept() method will block the executing thread until the reception * of the client's request. If there is no request received, but the accept() is not blocked, * there must be a bug in the program. Normally, this is due to the usage of a port that is * occupied at the same time by another program. It is to say that ServerSocket is not * successfully binded. * <p> * In the client part programming, we should create a socket like this: <code> * new Socket(InetAddress server, port)</code> to establish a connection to the server. * <p> * Both the server socket object and the client socket object can call the method getOutputStream() * and getInputStream(). So these sockets use them to communicate, instead of send() and receive() * for the DatagramSocket. * @author HAN * */ public class Weather extends Thread{ String weather ="节目预告: 八点有大型晚会,请收听"; int port =9898; InetAddress iaddress;//没法初始化,这里只能声明。因为初始化new对象时要抛出异常所以在成员变量区域是语法通不过的。 //MulticastSocket socket; DatagramSocket socket; //在构造方法中初始化成员变量 Weather(){ /*try { //A multicast group is specified by a class D IP address //and by a standard UDP port number. //Class D IP addresses are in the range 224.0.0.0 to 239.255.255.255, inclusive. //The address 224.0.0.0 is reserved and should not be used. iaddress=InetAddress.getByName("233.0.0.0"); socket=new MulticastSocket(port); socket.setTimeToLive(1); socket.joinGroup(iaddress); }catch(Exception e){ e.printStackTrace(); }*/ try { iaddress=InetAddress.getByName("233.0.0.0"); socket=new DatagramSocket(); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override //最简单的方法也就是建立一个线程来运行 public void run(){ while(true){ byte[] data=weather.getBytes(); DatagramPacket packet=new DatagramPacket(data,data.length,iaddress,port); // System.out.println(weather); System.out.println(new String(data)); try { socket.send(packet); sleep(3000);//线程休眠3秒 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args){ Weather w=new Weather(); w.start(); } }
package com.han; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.*; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** * This is the receive part. * @author HAN * */ public class Receive extends JFrame implements Runnable, ActionListener{ private static final long serialVersionUID = 3362377947503474102L; int port=9898; InetAddress group; MulticastSocket socket; //socket sends and receives the packet. DatagramPacket packet; JButton ince=new JButton("开始接收"); JButton stop=new JButton("停止接收"); JTextArea inceAr=new JTextArea(10,20); JTextArea inced=new JTextArea(10,20); Thread thread; boolean b = false; // byte[] buf=new byte[30]; // If the message is longer than the packet's length, the message is truncated. byte[] buf=new byte[1024]; //在构造方法中设置具体参数特性,也就是初始化 public Receive(){ super("广播数据报"); thread=new Thread(this); ince.addActionListener(this); stop.addActionListener(this); inceAr.setForeground(Color.blue); JPanel north=new JPanel(); north.add(ince); north.add(stop); add(north,BorderLayout.NORTH); JPanel center=new JPanel(); JScrollPane sp=new JScrollPane(inceAr); JScrollPane sp2=new JScrollPane(inced); inceAr.setLineWrap(true); inceAr.setEditable(false); inced.setLineWrap(true); inced.setEditable(false); center.add(sp); center.add(sp2); add(center,BorderLayout.CENTER); pack(); //JFrame inherited from Window validate(); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); try { socket=new MulticastSocket(port); //A multicast group is specified by a class D IP address //and by a standard UDP port number. //Class D IP addresses are in the range 224.0.0.0 to 239.255.255.255, inclusive. //The address 224.0.0.0 is reserved and should not be used. group=InetAddress.getByName("233.0.0.0"); socket.joinGroup(group); packet=new DatagramPacket(buf,buf.length); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run(){ while(true){ try { socket.receive(packet); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // String message=new String(buf); String message=new String(packet.getData(),0,packet.getLength());//very important !! // System.out.println(message.length()); inceAr.setText("正在接受的内容: \n"+message); inced.append(message+"\n"); if(b==true){ break; } } } public void actionPerformed(ActionEvent e){ Object object=e.getSource(); if(object==ince){ //If this thread is already on the state "run", do nothing. if(!thread.isAlive()){ thread=new Thread(this); thread.start(); ince.setBackground(Color.red); stop.setBackground(Color.yellow); b=false; } } if(object==stop){ ince.setBackground(Color.yellow); stop.setBackground(Color.red); b=true; } } public static void main(String[] args){ @SuppressWarnings("unused") Receive rec=new Receive(); // rec.setSize(460, 200);//提供了额外设置窗体大小的方式 } }
posted on 2012-01-16 07:20 java课程设计例子 阅读(206) 评论(0) 编辑 收藏 举报