Java数据报编程之组播

转自其他网站



核心提示:在信息时代,网络技术应用已经很普通。其中很多应用都依赖于从一个主机向多个主机或者从多个主机向多个主机发送同一信息的能力,在Internet 上分发的数目可能达数十万台,这些都需要更高的带宽,并且大大超出了单播的能力。一种能最大限度地利用现有带宽的重

在信息时代,网络技术应用已经很普通。其中很多应用都依赖于从一个主机向多个主机或者从多个主机向多个主机发送同一信息的能力,在Internet 上分发的数目可能达数十万台,这些都需要更高的带宽,并且大大超出了单播的能力。一种能最大限度地利用现有带宽的重要技术是IP 组播。


1 IP 组播技术的概念

IP 组播技术,是一种允许一台或多台主机(组播源)发送单一数据包到多台主机(一次的,同时的)的TCP/IP 网络技术, 是一点对多点的通信。在网络多媒体广播的应用中,当需要将一个节点的信号传送到多个节点时,无论是采用重复点对点通信方式,还是采用广播方式,都会严重浪费网络带宽,只有组播才是最好的选择。组播能使一个或多个组播源只把数据包发送给特定的组播组,而只有加入该组播组的主机才能接收到数据包。

2 IP 组播地址

IP 组播通信依赖于IP 组播地址,在IPv4 中它是一个DIP 地址,范围从224.0.0.0239.255.255.255 ,并被划分为局部链接组播地址、预留组播地址和管理权限组播地址三类。其中,局部链接组播地址范围在224.0.0.0~224.0.0.255 ,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP 包;预留组播地址为224.0.1.0~238.255.255.255 ,可用于全球范围(如 Internet )或网络协议;管理权限组播地址为239.0.0.0~239.255.255.255 ,可供组织内部使用,类似于私有IP 地址,不能用于Internet ,可限制组播范围。

3 .组播组

使用同一个IP 组播地址接收组播数据包的所有主机构成了一个主机组,也称为组播组。一个组播组的成员是随时变动的,一台主机可以随时加入或离开组播组,组播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个组播组。此外,不属于某一个组播组的主机也可以向该组播组发送数据包。

本文使用MulticastSocket 类的实例编写组播应用,MulticastSocket 类提供连接和离开组播等操作。

MultiSender 类清单

1.       package  recmail.multiservice;   

2.         

3.       import  java.net.*;   

4.       import  java.io.IOException;   

5.         

6.       /**  

7.        *  该类封装了MulticastSocket, 完成了MulticastSocket 类实例的创建、初始化功能,  

8.        *  并提供了一个发送数据的接口.  

9.        */   

10.       

11.     public   class  MultiSender {   

12.        public   static   final   int  MultiSender_Port= 4099 ;   

13.        private  MulticastSocket road;   

14.        private  InetAddress ia;   

15.       

16.        public  MultiSender() {   

17.          try  {   

18.       

19.            // 组播地址   

20.           ia = InetAddress.getByName( "239.66.69.18" );   

21.           road =  new  MulticastSocket(MultiSender_Port);   

22.           road.joinGroup(ia);   

23.         }   

24.          catch  (UnknownHostException ex) {   

25.         }   

26.          catch  (IOException ex1) {   

27.         }   

28.       }   

29.        public  InetAddress getInetAddress(){   

30.          return  ia;   

31.       }   

32.        public  MulticastSocket getRoad(){   

33.          return  road;   

34.       }   

35.        public   void  send( byte [] b){   

36.         DatagramPacket dp =  new  DatagramPacket(b,  0 , b.length,   

37.                                                    ia, MultiSender.MultiSender_Port);   

38.          try  {   

39.           road.send(dp);   

40.         }   

41.          catch  (IOException ex) {   

42.           ex.printStackTrace();   

43.         }   

44.       }   

45.     }   

 

ImageServer , 使用上面的类发送文件数据.

1.       package  recmail.multiservice;   

2.       import  java.io.*;   

3.       import  javax.swing.Timer;   

4.       import  java.awt.event.*;   

5.       import  java.awt.image.*;   

6.       import  java.util.*;   

7.       import  java.io.FileFilter;   

8.       import  java.io.FilenameFilter;   

9.         

10.     /**  

11.      *  本类利用MultiSender 类发送文件数据到一个组播组发送数据.  

12.      */   

13.       

14.     public   class  ImageServer   

15.          extends  Thread  implements  ActionListener {   

16.       Timer timer;   

17.       BufferedImage image;   

18.       ArrayList streamfragments;   

19.        int  counter =  0 ;   

20.        byte [] imagebyte;   

21.       ArrayList listener;   

22.       MultiSender sender;   

23.       

24.        public  ImageServer(ArrayList f) {   

25.         timer =  new  Timer( 50 this );   

26.         timer.addActionListener( this );   

27.         listener =  new  ArrayList();   

28.         streamfragments = f;   

29.         sender =  new  MultiSender();   

30.         timer.start();   

31.       }   

32.       

33.        public   void  addDataSwapListener(DataSwapListener dsl) {   

34.         listener.add(dsl);   

35.       }   

36.       

37.        public   void  removeDataSwapListener(DataSwapListener dsl) {   

38.         listener.remove(dsl);   

39.       }   

40.       

41.        private   void  processEvent() {   

42.          for  ( int  i =  0 ; i <  this .listener.size(); i++) {   

43.           DataSwapEvent dse =  new  DataSwapEvent();   

44.           ( (DataSwapListener) this .listener.get(i)).OnDataSendFinished( this , dse);   

45.         }   

46.       }   

47.       

48.        public   void  actionPerformed(ActionEvent e) {   

49.         DataPacket dp =  new  DataPacket(streamfragments.get(counter).toString());   

50.         DataEntry de;   

51.          try  {   

52.           ArrayList al = dp.getDataPackets();   

53.           Thread.sleep( 1000 );   

54.           System.out.println(streamfragments.get(counter).toString());   

55.            for  ( int  i =  0 ; i < al.size(); i++) {   

56.             imagebyte = ( (DataEntry) al.get(i)).getByte();  //(byte[]) al.get(i);   

57.             sender.send(imagebyte);   

58.           }   

59.            this .processEvent();   

60.         }   

61.          catch  (Exception ex) {   

62.           System.out.println(ex);   

63.         }   

64.         counter++;   

65.          if  (counter >= streamfragments.size())   

66.           counter =  0 ;   

67.       }   

68.       

69.        public   void  run() {   

70.          while  ( true ) {   

71.            try  {   

72.              this .sleep( 20 );   

73.           }   

74.            catch  (InterruptedException ex) {   

75.           }   

76.         }   

77.       }   

78.       

79.        public   static   void  main(String[] args) {   

80.         String file[];   

81.         ArrayList al =  new  ArrayList();   

82.         String path =  "E://mzip//" ;    

83.         File f =  new  File(path);   

84.         file = f.list();   

85.          for  ( int  i =  0 ; i < file.length; i++) {   

86.            if  (file[i].endsWith( "jpg" ) || file[i].endsWith( "bmp" ))    

87.             al.add(path + file[i]);   

88.         }   

89.         ImageServer is =  new  ImageServer(al);   

90.         is.start();   

91.       }   

92.     }   

1.       package  recmail.multiservice;   

2.         

3.       import  java.net.*;   

4.       import  java.io.*;   

5.       import  java.awt.image.*;   

6.       /**  

7.        *  该类封装了MulticastSocket, 完成了MulticastSocket 类实例的创建、初始化功能,  

8.        *  并提供一个接收数据的线程, 在判断接收完毕后产生事件, 更新UI 显示.  

9.        *  该类由testFrame 使用.  

10.      */   

11.     public   class  ImageShow   

12.          extends  DataSwapListenerAdapter   

13.          implements  Runnable {   

14.        private  InetAddress ia;   

15.        private   int  port =  4099 ;   

16.        private  MulticastSocket road;   

17.       DataSwapEvent dsevent;   

18.       java.awt.image.BufferedImage bi;   

19.       

20.        public  ImageShow() {   

21.         dsevent =  new  DataSwapEvent( this );   

22.          try  {   

23.           ia = InetAddress.getByName( "239.66.69.18" );   

24.           road =  new  MulticastSocket(port);   

25.           road.joinGroup(ia);   

26.         }   

27.          catch  (IOException ex) {   

28.         }   

29.       }   

30.       

31.        public   void  run() {   

32.          byte [] buffer =  new   byte [DataPacket.DataSwapSize];   

33.         DatagramPacket packet =  new  DatagramPacket(buffer, buffer.length);   

34.         DataPacket dp =  new  DataPacket();   

35.          while  ( true ) {   

36.           packet.setLength(buffer.length);   

37.           System.out.println( "wait .. " );   

38.            try  {   

39.             road.receive(packet);   

40.             dp.Add(packet.getData());   

41.              if  (dp.isFull()) {   

42.               dsevent.setImage(dp.Gereratedata());   

43.                this .processRecvFinishedEvent(dsevent);   

44.               dp =  new  DataPacket();   

45.             }   

46.           }   

47.            catch  (IOException ex) {   

48.             System.out.println(ex);   

49.           }   

50.         }   

51.       }   

52.     }   

接收端界面类:

1.       package  recmail.multiservice;   

2.         

3.       import  javax.swing.*;   

4.       import  java.awt.*;   

5.       import  java.awt.image.*;   

6.         

7.       /**  

8.        *  该类使用ImageShow 更新显示的图象.  

9.        */   

10.       

11.     public   class  testFrame   

12.          extends  JApplet   

13.          implements  DataSwapListener {   

14.        private  JPanel root;   

15.       JLabel label;   

16.       JImagePanel ip;   

17.       java.awt.Image bi;   

18.       

19.        public  testFrame() {   

20.         initmain();   

21.       }   

22.       

23.        public   void  init() {   

24.         initmain();   

25.          this .setContentPane(root);   

26.         ImageShow is =  new  ImageShow();   

27.         is.addDataSwapListener( this );   

28.         Thread thread =  new  Thread(is,  "test" );   

29.         thread.start();   

30.       }   

31.       

32.        public   static   void  main(String[] args) {   

33.         testFrame test =  new  testFrame();   

34.         test.go( new  JFrame());   

35.         ImageShow is =  new  ImageShow();   

36.         is.addDataSwapListener(test);   

37.         Thread thread =  new  Thread(is,  "test" );   

38.         thread.start();   

39.       }   

40.       

41.        public   void  go(JFrame frame) {   

42.         frame.setContentPane(root);   

43.         frame.setSize( 300 200 );   

44.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   

45.         frame.validate();   

46.         frame.setVisible( true );   

47.       }   

48.       

49.        public   void  initmain() {   

50.         root =  new  JPanel();   

51.          //label = new JLabel();   

52.         ip =  new  JImagePanel();   

53.         root.setLayout( new  BorderLayout( 5 5 ));   

54.         root.add(ip, BorderLayout.CENTER);   

55.       }   

56.       

57.        public   void  setRefreshImage(java.awt.image.BufferedImage img) {   

58.          this .bi = img;   

59.         ip.setImage(bi);   

60.       }   

61.       

62.        public   void  paint(Graphics g) {   

63.          super .paint(g);   

64.       }   

65.       

66.        public   void  paintComponents(Graphics g) {   

67.          super .paintComponents(g);   

68.         Graphics g1 = root.getGraphics();   

69.         g1.drawImage(bi,  0 0 this );   

70.       }   

71.       

72.        public   void  OnDataSendFinished(Object s, DataSwapEvent e) {   

73.       

74.       }   

75.       

76.        public   void  OnDataRecvFinished(Object s, DataSwapEvent e) {   

77.          this .bi = e.getImage();   

78.         ip.setImage(bi);   

79.         System.out.println( "recv Finished!" );   

80.       }   

81.     }   

到此, 这个多播程序编写完毕, 通过这个程序可以看出在Java 中进行组播编程有两个特点, 一是使用JavaMulticastSocket, 二是使用组播地址配置MulticastSocket 实例.

数据报编程的全部内容已结束, 如果要改进, 可以在两个方面进行, 一个是改善传输的可靠性方面, 一个是采用数据收发的异步方面, 因为在J2SDK1.4MulticastSocket 类增加了方法getChannel().

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值