170327网络编程之基于组播技术的网络聊天系统的设计与实现

7.基于组播技术的网络聊天系统的设计与实现
题目要求:
(1) 采用UDP组播技术
(2) 支持100人加入组播组
(3) 加入组播组的成员可以看到已加入该组播组的成员
(4) 各组成员即可以给该组其它成员发送信息,也可以给该组的特定成员发送信

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;


public class groupV extends JFrame {
    String GroupAddress;
    int GroupPort;
    JPanel jpCenter,jpBottom,jpBFirst,jpBSecond,jpBThird;
    JList jlistContent;
    JScrollPane jspContent;
    JLabel jlbMtAddress,jlbMtPort,jlbSend,jlbFriend,jlbPort;
    JTextField jtxtMultiAddress,jtxtMultiPort,jtxtSend,jtxtPort;
    JButton jbJoin,jbExit,jbSend,jbSendToSB;
    JComboBox<String> jcbFriend;
    MulticastSocket socket=null;
    DatagramPacket packet=null;
    boolean isExit=false;
    
    DefaultListModel<String> dlm=null;
    
    public groupV(){
        dlm=new DefaultListModel();
        this.setTitle("组播聊天窗口");
        this.setLocation(100,100);
        this.setSize(800,600);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        
        this.setLayout(new BorderLayout());
        
        jpCenter=new JPanel();
        
        jlistContent=new JList();
        jspContent=new JScrollPane(jlistContent);
        this.add(jspContent,BorderLayout.CENTER);
            
        
        jpBottom=new JPanel(new GridLayout(3,1));
    
        //First
        jpBFirst=new JPanel();
        jlbMtAddress=new JLabel("组播地址:");
        jtxtMultiAddress=new JTextField(30);
        jlbMtPort=new JLabel("组播端口:");
        jtxtMultiPort=new JTextField(5);
        jbJoin=new JButton("加入组播");
        jbExit=new JButton("退出");
        jpBFirst.add(jlbMtAddress);
        jpBFirst.add(jtxtMultiAddress);
        jpBFirst.add(jlbMtPort);
        jpBFirst.add(jtxtMultiPort);
        jpBFirst.add(jbJoin);
        jpBFirst.add(jbExit);
        jpBottom.add(jpBFirst);
        
        //Second
        jpBSecond=new JPanel();
        jlbFriend=new JLabel("在线朋友:");
        jcbFriend=new JComboBox<String>();
        jcbFriend.setPreferredSize(new Dimension(400,20));
        jlbPort=new JLabel("端口:");
        jtxtPort=new JTextField(5);
                
        jpBSecond.add(jlbFriend);
        jpBSecond.add(jcbFriend);
        jpBSecond.add(jlbPort);
        jpBSecond.add(jtxtPort);
        jpBottom.add(jpBSecond);
                
        //Third
        jpBThird=new JPanel();
        jlbSend=new JLabel("发送信息:");
        jtxtSend=new JTextField(30);
        jbSend=new JButton("发送到组");
        jbSendToSB=new JButton("发送给选定好友");
        jpBThird.add(jlbSend);
        jpBThird.add(jtxtSend);
        jpBThird.add(jbSend);
        jpBThird.add(jbSendToSB);
        jpBottom.add(jpBThird);
        
        this.add(jpBottom,BorderLayout.SOUTH);
        this.setVisible(true);
        
        /*加入组播*/ 
        jbJoin.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                try {
                    getGroupAddress();
                    getGroupPort();
                    try {
                        socket=new MulticastSocket(GroupPort);
                        setJList("初始化socket成功!!");
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        setJList("初始化组播socket失败  "+e1.getMessage());
                    }
                    
                    //获得地址
                    InetAddress address=InetAddress.getByName(GroupAddress);
                    //加入组播
                    socket.joinGroup(address);
                    
                    socket.setLoopbackMode(false);//??
                    
                    //在下拉列表添加当前主机地址
                    jcbFriend.addItem(getSplit(getLocalhost()));
                    
                    //接受信息
                    new Thread(new Runnable(){
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            while(!isExit){
                                
                                try {
                                    byte[] buffer=new byte[1024];
                                    DatagramPacket mypacket=new DatagramPacket(buffer,0,buffer.length);
                                    socket.receive(mypacket);
                                    String recvInfo=new String(mypacket.getData(),0,mypacket.getLength());
                                    
                                    //新朋友来到
                                    if(recvInfo.equals("Hello")){
                                        String packetIPMs=mypacket.getAddress().toString();
                                        
                                        //判断ip是否出现过 isIPExist()
                                        if(isIPExist(getSplit(packetIPMs))){//yes
                                            setJList("将IP添加到列表:"+getSplit(packetIPMs)+"已存在");
                                        }else{
                                            setJList("将IP添加到列表:"+getSplit(packetIPMs));
                                            jcbFriend.addItem(getSplit(packetIPMs));
                                        }
                                    }
                                    
                                    setJList("收到组播信息:"+recvInfo);
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }        
                            }
                        }
                    }).start();
                    sendToGroup("Hello");
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    setJList("加入组播组失败!!"+e.getMessage());
                }
                
            }
            
        });
        /*退出*/
        jbExit.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                try {
                    getGroupAddress();
                    getGroupPort();
                    socket.leaveGroup(InetAddress.getByName(GroupAddress));
                    for(int i=0;i<jcbFriend.getItemCount();i++){
                         System.out.println(jcbFriend.getItemAt(i));
                         String is=jcbFriend.getItemAt(i).trim();
                         if(getSplit(getLocalhost()).equals(is)){
                             jcbFriend.removeItemAt(i);
                         }
                    }
                    setJList("已退出组播!!");
                } catch (UnknownHostException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
            
        });
        /*发送到组*/
        jbSend.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                String groupMessage=jtxtSend.getText().trim();
                sendToGroup(groupMessage);
            }
        });
        
        
        /*发送给指定好友*/
        jbSendToSB.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                String personalMessage=jtxtSend.getText().trim();
                sendToSB(personalMessage);
            }
        });
        
    }
    
    public static void main(String[] args){
        new groupV();
    }
    /*------------以下是调用函数-----------------*/
    //添加消息到消息列表
    private void setJList(String info){
        dlm.addElement(info);
        jlistContent.setModel(dlm);
    }
    //发送信息到组播
    private void sendToGroup(String info)
    {
        DatagramSocket sendSocket=null;
        try {
            getGroupAddress();
            getGroupPort();
            sendSocket=new DatagramSocket();
            byte[] buffer=info.getBytes();
            InetAddress address=InetAddress.getByName(GroupAddress);
            DatagramPacket sendPacket=new DatagramPacket(buffer,0,buffer.length,address,GroupPort);
            sendSocket.send(sendPacket);
            setJList("发送组播信息成功!!"+info);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            //e1.printStackTrace();
            setJList("发送信息失败!!"+e1.getMessage());
        }finally{
            sendSocket.close();
        }
    }
 
    //发送信息给指定好友
    private void sendToSB(String info1)
    {
        DatagramSocket sendSbSocket=null;
        try {
            sendSbSocket=new DatagramSocket();
            String currentFriend=jcbFriend.getSelectedItem().toString().trim();
            int cport=Integer.parseInt(jtxtPort.getText().toString().trim());
            byte[] Message=info1.getBytes();
            InetAddress caddress=InetAddress.getByName(currentFriend);
            DatagramPacket sendSbPacket=new DatagramPacket(Message,0,Message.length,caddress,cport);
            sendSbSocket.send(sendSbPacket);
            setJList("发送给朋友的信息成功:"+info1);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            setJList("发送给朋友的信息失败"+e.getMessage());
        }
        
    }
    
    //获得组播地址
    private String getGroupAddress(){
        GroupAddress=jtxtMultiAddress.getText().trim();
        return GroupAddress;
    }
    //获得组播端口
    private int getGroupPort(){
        GroupPort=Integer.parseInt(jtxtMultiPort.getText().trim());
        return GroupPort;
    }
    //获得当前主机地址(未分割“/”)
    private String getLocalhost() throws UnknownHostException{
        String localhost = InetAddress.getLocalHost().toString();
        String a[]=localhost.split("/");
        String SplitLocalhost=a[1];
        return localhost;
    }
    //分割地址(分割“/”)
    private String getSplit(String spt) throws UnknownHostException{
        String a[]=spt.split("/");
        String Split=a[1];
        return Split;
    }
    private boolean isIPExist(String testIP){
        for(int i=0;i<jcbFriend.getItemCount();i++){
             String is=jcbFriend.getItemAt(i).trim();
             if(is.equals(testIP)){
                 return true;
             }
        }
        return false;
    }
}

有待加强

 组播的ppt待上传

原文地址:https://www.cnblogs.com/liao13160678112/p/6628877.html