您的位置:首页 > 编程语言 > Java开发

Java数据报编程之组播

2010-03-16 23:57 363 查看
转自其他网站

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

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

1

.IP
组播技术的概念


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

2

.IP
组播地址


IP
组播通信依赖于IP
组播地址,在IPv4
中它是一个D
类IP
地址,范围从224.0.0.0
到239.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"
);

1444f
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
中进行组播编程有两个特点,
一是使用Java
的MulticastSocket
类,
二是使用组播地址配置MulticastSocket
实例.

数据报编程的全部内容已结束,
如果要改进,
可以在两个方面进行,
一个是改善传输的可靠性方面,
一个是采用数据收发的异步方面,
因为在J2SDK1.4
中MulticastSocket
类增加了方法getChannel().
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息