基于UDP的组播通信
在Java实现基于UDP协议的发送端与接收端通信中,我们可以知道它的一些主要操作:
在发送端:1,创建绑定指定端口的发送接口:DatagramSocket(port)
2,创建绑定主机IP的目标地址:InetAddress
3,创建存放要发送的数据的数据包:DatagramPacket
4,发送接口发送数据包
在接收端:1,创建绑定指定端口的接受接口:DatagramSocket(port)
2,创建接受信息的数据包:DatagramPacket
3,接收点接收数据包
以上操作只能实现在同一局域网(路由器)内实现单个发送端对单个接收端之间的通信,即对
点模式,而这次组播模式系统结构,是一个端上的消息发送给其他许多端,其主要操作如下:
发送消息:
1,创建组播发送信息接口:MulticastSocket
2,创建绑定指定IP的地址对象:InetAddress
注:在组播通信中,IP地址在tcp/ip协议中被规定为224.0.0.0~239.225.225.225中
的地址,而要参与组播通信的话,所有主机都必须加入到同一个IP地址,并且要在同一端口发
消息。
3,创建存放要发送的数据的数据包:DatagramPacket
4,发送接口发送数据包
接收组播消息:
1,创建组播接收信息接口:MulticastSocket
2,创建绑定指定IP的地址对象:InetAddress
3,组播接口接口加入到组中:multicastSocket.joinGroup(inetAddress);
4,创建接收消息的数据包:DatagramPacket
5,组播接口接收数据包:multicastSocket.receive(datagramPacket);
由以上可以看出,对点模式与组播模式只有小部分不同:
一个是将DatagramSocket换成MulticastSocket:DatagramSocket只允许数据报发给指定的目
标地址,而MulticastSocket可以将数据报以广播的方式发送到多个客户端。
另一个就是在接收组播消息时需要把组播接口加入到组中,就好像微信加群一样,这样才能接
收到组内的消息;若要离开某一组,可调用MulticastSocket的leaveGroup(inetAddress)方法
。
此处贴上一个简单组播群聊系统为例,以作参考:
public class Chat extends Thread {
private static int portTem=9999;//端口
private static String mutiAddr="230.0.0.1";//组播IP地址
private InetAddress inetAddress;//组播消息的目标地址
private MulticastSocket multicastSocket;//本机组播发送端
//显示接收到消息的组件
private JTextArea jta_recive=new JTextArea(10,25);
public Chat(){
try{
inetAddress = InetAddress.getByName(mutiAddr);
multicastSocket = new MulticastSocket();
setUpUI();
}catch(Exception ef){ef.printStackTrace();}
}
//启动聊天界面
public void setUpUI(){
JFrame jf=new JFrame();
jf.setTitle("组播聊天示例");
FlowLayout fl=new FlowLayout();
jf.setLayout(fl);
jf.setSize(300,400);
JLabel la_name=new JLabel("接收到的消息:");
JLabel la_users=new JLabel("你的名字:");
final JTextField jtf_name=new JTextField(5);//用户名输入框
final JTextField jtf_sned=new JTextField(20);//发送输入框
JButton bu_send=new javax.swing.JButton("Send");
jf.add(la_name);
jf.add(jta_recive);
jf.add(la_users);
jf.add(jtf_name);
jf.add(jtf_sned);;
jf.add(bu_send);
//发送事件监听器
ActionListener sendListener=new ActionListener(){
public void actionPerformed(ActionEvent e){
String name=jtf_name.getText();
String msg=jtf_sned.getText();
msg=name+"说:"+msg;
sendMsg(msg);//发送一条组播消息
jtf_sned.setText("");
}
};
bu_send.addActionListener(sendListener);
//jtf_sned.addActionListener(sendListener);
jf.setVisible(true);
jf.setDefaultCloseOperation(3);
}
//发送一条消息到组中
public void sendMsg(String msg){
try{
byte [] data = (msg).getBytes();
DatagramPacket datagramPacket = new DatagramPacket(data,
data.length, inetAddress, portTem);
multicastSocket.send(datagramPacket);
}catch(Exception ef){ef.printStackTrace();}
}
//接收组播消息线程
public void run(){
try {//在同一端口上创建接收组播Socket对象
MulticastSocket recvSocket=new MulticastSocket(portTem);
recvSocket.joinGroup(inetAddress);//加入到组中,否则收不到
消息
while (true) {
byte [] data = new byte [100];
DatagramPacket datagramPacket = new
DatagramPacket(data,data.length);
recvSocket.receive(datagramPacket);
String input=new String(data).trim();
jta_recive.append(input+"rn");
}
}
catch (Exception exception) {exception.printStackTrace();}
}
//主函数
public static void main(String [] arstring){
Chat chat=new Chat();
chat.start();
}
}