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待上传