zoukankan      html  css  js  c++  java
  • java模拟一个简单的QQ

    v 项目源码

      https://github.com/hjzgg/java_QQ

    v 标题效果

          

    package testFour;
    
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.BindException;
    import java.net.ServerSocket;
    import java.util.Iterator;
    
    import javax.imageio.ImageIO;
    import javax.imageio.ImageReader;
    import javax.imageio.stream.ImageInputStream;
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextPane;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Document;
    import javax.swing.text.SimpleAttributeSet;
    import javax.swing.text.StyleConstants;
    
    public class QQ {
        public static final int PICUTER = 1; 
        public static final int FILE = 2; 
        public static final int PARAGRAPH = 3; 
        public static final int SEND = 1; 
        public static final int RECEIVE = 2; 
        public static final int FILEX = 3;
        
        public static int getUnusedPort() throws BindException{
            int port;
            for(port = 10000 ; port <= 65535; ++port){
                ServerSocket ss = null; 
                try {
                    ss = new ServerSocket(port);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(ss != null) break;
            }
            if(port > 65535)
                throw new BindException("没有可用的端口!");
            return port;
        }
        
        public synchronized static void setTextPane(JTextPane tp, byte[] bt, int len, int flag, int tag){
             ImageIcon myIcon = null;
             if(tag == SEND)
                 myIcon = new ImageIcon("ff.jpg");
             else if(tag == RECEIVE)
                 myIcon = new ImageIcon("gg.jpg");
             else if(tag == FILEX)
                 myIcon = new ImageIcon("kk.jpg");
             
             SimpleAttributeSet set = new SimpleAttributeSet();
             Document doc = tp.getStyledDocument();
             
             if(tag == SEND || tag == RECEIVE){
                  tp.setCaretPosition(doc.getLength());
                  JLabel fileLabel = new JLabel("", myIcon, JLabel.CENTER);
                  tp.insertComponent(fileLabel);
             }
             
             if(flag == PARAGRAPH){
                 FontMetrics fm = tp.getFontMetrics(tp.getFont());
                 int paneWidth = tp.getWidth();
                 String text = new String(bt, 0, len);
                 
                 if( tag/3 == SEND ){
                     StyleConstants.setForeground(set, new Color(0,255,0));//设置文字颜色
                     StyleConstants.setFontSize(set, 15);//设置字体大小
                 }
                 else if( tag/3 == RECEIVE){
                     StyleConstants.setForeground(set, new Color(0,0,0));//设置文字颜色
                     StyleConstants.setFontSize(set, 15);//设置字体大小
                 }
                 
                 try
                  {
                      for(int i = 0, cnt = 0; i < text.length(); ++i){
                          if((cnt += fm.charWidth(text.charAt(i))) >= paneWidth){
                              cnt = 0;
                              doc.insertString(doc.getLength(), "
    ", set);
                              continue;
                          }
                          doc.insertString(doc.getLength(), String.valueOf(text.charAt(i)), set);
                      }
                      doc.insertString(doc.getLength(), "
    ", set);
                      
                      tp.setCaretPosition(doc.getLength());//最简单的设置滚动条的位置到最后输出文本的地方
                                                             //就是将JTextPane中的插入符的位置移动到文本的末端!
                  }
                  catch (BadLocationException e)
                  {
                  }
                 
             } else if(flag == PICUTER) {
                
                 try{
                         InputStream is = new ByteArrayInputStream(bt, 0, len);
                         ImageInputStream iis = ImageIO.createImageInputStream(is);
                         Iterator<ImageReader> itImage = ImageIO.getImageReaders(iis);
                         if(itImage.hasNext()){
                             ImageReader reader = itImage.next();
                             ImageIcon ii = new ImageIcon( bt, reader.getFormatName() );
                             tp.setCaretPosition( doc.getLength() );
                             tp.insertComponent( new PicuterPanel(ii) );
                             doc.insertString(doc.getLength(), "
    ", set);
                         }
                 }catch(IOException ex){
                         ex.printStackTrace();
                 }catch(BadLocationException e1){
                       
                 }
                 
             } else if(flag == FILE) {
                  try{
                      tp.setCaretPosition(doc.getLength());
                      JLabel fileLabel = new JLabel(new String(bt, 0, len), myIcon, JLabel.LEFT);
                      tp.insertComponent(fileLabel);
                      doc.insertString(doc.getLength(), "
    ", set);
                  }catch (BadLocationException e) {
                      e.printStackTrace();
                }
             }
        }
    }
    
    class PicuterPanel extends JPanel{
        private ImageIcon ii;
        public PicuterPanel(ImageIcon ii){
            this.ii = ii;
            setPreferredSize(new Dimension(200, 300));
            setBackground(new Color(255, 255, 255));
        }
        
        protected void paintComponent(Graphics g) {
              super.paintComponent(g);
              g.drawImage(ii.getImage(), 0, 0, 200, 300, 0, 0, ii.getIconWidth(), ii.getIconHeight(), this);
        }
    }
    View Code
    package testFour;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dialog;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.Frame;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.Map;
    import java.util.Random;
    import java.util.Set;
    import java.util.TreeMap;
    import java.util.TreeSet;
    
    import javax.swing.BoxLayout;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JMenuItem;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JPopupMenu;
    import javax.swing.JScrollBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    import javax.swing.ScrollPaneConstants;
    
    
    
    public class QQDialog extends Frame{
            private JPanel QQP = new JPanel();
            private JButton myFriend = new JButton("QQ好友>>");
            private JPanel funP = new JPanel();
            private JButton add = new JButton("添加好友");
            private JButton serach = new JButton("查询好友");
            private JPanel pp = new JPanel();
            private JPanel tmp = null;
            private final int QQPheight = 397;
            private JScrollPane jsp = new JScrollPane(QQP);
            private static Set<String>QQset;//IP的集合
            private static Map<String, QQFrame>QQmap;//IP到对通信窗口的映射
            private static Map<String, String>nameToIP;//姓名到IP的映射
            ImageIcon[] ii = new ImageIcon[3];
            
            public static Map<String, QQFrame> getMap(){
                return QQmap;
            }
            
            public static Set<String> getSet(){
                return QQset;
            }
            
            public static Map<String, String> getNameToIP(){
                return nameToIP;
            }
            
            public QQDialog(){
                
                QQset = new TreeSet<String>();
                QQmap = new TreeMap<String, QQFrame>();
                nameToIP = new TreeMap<String, String>();
                
                ii[0] = new ImageIcon("ff.jpg");
                ii[1] = new ImageIcon("gg.jpg");
                ii[2] = new ImageIcon("kk.jpg");
                setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
                jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
                jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                pp.add(jsp);
                pp.setLayout(new BoxLayout(pp, BoxLayout.Y_AXIS));
                QQP.setLayout(new BoxLayout(QQP, BoxLayout.Y_AXIS));
                JPanel pmyFriend = new JPanel();
                pmyFriend.setLayout(new BorderLayout());
                pmyFriend.add(myFriend, "Center");
                pmyFriend.setPreferredSize(new Dimension(300, 20));
                add(pmyFriend);
                pp.setPreferredSize(new Dimension(300, 400));
                add(pp);
                add(funP);
                
                JLabel myself = null;
                try {
                    myself = new JLabel(InetAddress.getLocalHost().getHostName() + ":" + InetAddress.getLocalHost().getHostAddress());
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                addLabelListener(myself);
                myself.setIcon(new ImageIcon("ff.jpg"));
                
                tmp = new JPanel();
                tmp.setLayout(new FlowLayout(FlowLayout.CENTER));
                tmp.setBackground(new Color(255, 0, 255));
                tmp.setPreferredSize(new Dimension(250, 60));
                tmp.add(myself);
                QQP.add(tmp);
                funP.setLayout(new FlowLayout(FlowLayout.CENTER));
                funP.add(add);
                funP.add(serach);
                
                myFriend.addMouseListener(new MouseAdapter() {
                    
                        public void mouseClicked(MouseEvent e) {//将好友面板进行收缩的效果!
                            if("QQ好友>>".equals(myFriend.getText())){
                                QQP.setVisible(false);
                                myFriend.setText("QQ好友<<");
                            }
                            else{
                                QQP.setVisible(true);
                                myFriend.setText("QQ好友>>");
                            }
                        }
    
                });
                
                add.addMouseListener(new MouseAdapter() {
                        public void mouseClicked(MouseEvent e) {
                            InputDialog dlg = new InputDialog();
                            if(dlg.key == InputDialog.CANCELBTN || dlg.key== 0) return;
                            Random rd = new Random();
                            int index = Math.abs(rd.nextInt()) % 3;
                            JLabel ll = new JLabel(dlg.getNameText() + ":" + dlg.getIPText(), ii[index], JLabel.LEFT);
                            QQset.add(dlg.getIPText());//将新增加的好友添加到集合中!
                            nameToIP.put(dlg.getNameText(), dlg.getIPText());
                            tmp = new JPanel();
                            tmp.setLayout(new FlowLayout(FlowLayout.CENTER));
                            tmp.setBackground(new Color(255, 0, 255));
                            
                            /*
                             *  BoxLayout布局简直是蛋疼的要命,一个面板X是BoxLayout布局,如果该面板添加一个面板Y的话
                             *  那么Y就会填充X面板!如果在添加一个面板Z, 那么Y, Z就会一起布满X面板!但是可以设置Y,Z面板
                             *  的比例! 如果X添加的是一个按钮或者标签时,还不能控制其大小.....无语了!
                             *  
                             *  下面的我的做法将标签添加到面板tmp中,然后再将tmp添加中QQP面板中!这样就可以控制标签的大小了!
                             *  再添加新的面板的时候,要设置一下之前面板的PreferredSize!保证每一个标签的距离适中!
                             *  也就是保证所有的添加的面板的高度之和 == QQP.getHeight();
                             * */
                            int cnt = QQP.getComponentCount();//显示QQ好友的个数!
                            if(cnt >= 1)
                                QQP.getComponent(cnt-1).setPreferredSize(new Dimension(250, 60));
                            int h = QQP.getHeight() - cnt*60;
                            if(h < 0) h=60;
                            tmp.setPreferredSize(new Dimension(250, h));
                            tmp.add(ll);
                            QQP.add(tmp);
                            QQP.add(tmp);
                            addLabelListener(ll);//给标签添加监听器
                            JScrollBar jsb = jsp.getVerticalScrollBar();
                            QQP.updateUI();//利用当前外观的值重置 UI 属性。 也可以保证滚动条随时的更新
                            //终于搞好了,将垂直滚动条自动的移动到最低端
                            jsp.getViewport().setViewPosition(new Point(0, jsp.getVerticalScrollBar().getMaximum()));
                        }
                });
                
                serach.addMouseListener(new MouseAdapter() {
                        public void mouseClicked(MouseEvent e) {
                              String name = JOptionPane.showInputDialog(null, "好友姓名", "好友查询", JOptionPane.OK_OPTION);
                              if(name == null)  return ;
                              
                              String ip = nameToIP.get(name);
                              
                              if(ip == null)
                                      JOptionPane.showMessageDialog(null, "好友不存在!", "查询结果", JOptionPane.OK_OPTION);
                              else{
                                  QQFrame fm = QQmap.get(ip);
                                  if(fm == null){
                                      try{
                                             String[] ipStr = ip.split("\.");//将字符串中的数字分离
                                             byte[] ipBuf = new byte[4];//存储IP的byte数组
                                             for(int i = 0; i < 4; i++){
                                                 ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);
                                             }
                                             fm = new QQFrame(name, ipBuf);
                                        }catch(RuntimeException ex){
                                             JOptionPane.showMessageDialog(null, ex.getMessage(), "Socket错误!", JOptionPane.OK_CANCEL_OPTION);
                                             return ;
                                        }
                                      QQmap.put(ip, fm);
                                  }
                                  else fm.requestFocus();
                              }
                        }
                });
                
                addWindowListener(new WindowAdapter() {
                        public void windowClosing(WindowEvent e) {
                            if(qr == null) System.out.println("hehe");
                            qr.setFlag();//udp服务线程停止
                            ss.setFlag();//tcp服务线程停止
                            System.exit(0);
                        }
                });
                
                QQP.setBackground(new Color(255, 0, 255));
                funP.setBackground(new Color(255, 255, 0));
                setResizable(false);
                setSize(300, 500);
                setLocation(500, 200);
                setVisible(true);
            }
            
            
            public void addLabelListener(final JLabel lab){
                 lab.setOpaque(true);
                 lab.setBackground(new Color(255, 255, 255));
                 lab.setPreferredSize(new Dimension(250, 55));
                 
                 String NameAndIP = lab.getText();
                  String name = NameAndIP.substring(0, NameAndIP.indexOf(':'));
                  String ip = NameAndIP.substring(NameAndIP.indexOf(':') + 1, NameAndIP.length());
                
                 nameToIP.put(name, ip);
                 QQset.add(ip);
                 
                 lab.addMouseListener(new MouseAdapter() {
                         Color oldC = lab.getBackground();
                         public void mouseEntered(MouseEvent e) {
                              lab.setBackground(new Color(0, 255, 0));
                         }
                         
                         public void mouseExited(MouseEvent e) {
                              lab.setBackground(oldC);
                         }
                         
                         public void mouseClicked(MouseEvent e) {
                              //打开通信窗口
                              if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2){
                                     String NameAndIP = lab.getText();
                                     String name = NameAndIP.substring(0, NameAndIP.indexOf(':'));
                                     if(QQmap.get(nameToIP.get(name)) != null){//这个好友的窗口已经存在!
                                        QQmap.get(nameToIP.get(name)).requestFocus();
                                        return ;
                                     }
                                     QQFrame fm = null;
                                    try{
                                         String[] ipStr = nameToIP.get(name).split("\.");//将字符串中的数字分离
                                         byte[] ipBuf = new byte[4];//存储IP的byte数组
                                         for(int i = 0; i < 4; i++){
                                             ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);
                                         }
                                         fm = new QQFrame(name, ipBuf);
                                         QQmap.put(nameToIP.get(name), fm);//name 和 窗口的映射!
                                    }catch(RuntimeException ex){
                                        JOptionPane.showMessageDialog(null, ex.getMessage(), "错误提示!", JOptionPane.OK_CANCEL_OPTION);
                                        return ;
                                    }
                              }
                              else if(e.getButton() == MouseEvent.BUTTON3){
                                   JPopupMenu pm = new JPopupMenu("胡峻峥");
                                   JMenuItem del = new JMenuItem("删除");
                                   del.setFont(new Font("华文行楷", Font.ITALIC, 20));
                                   del.setForeground(new Color(255, 0, 0));
                                   del.addActionListener(new ActionListener() {
                                        public void actionPerformed(ActionEvent e) {
                                            int choose = JOptionPane.showConfirmDialog(null, "确定删除!", "删除对话框", JOptionPane.YES_NO_OPTION);
                                               if(choose == JOptionPane.OK_OPTION){
                                                   QQP.remove(lab.getParent());
                                                   int cnt = QQP.getComponentCount();
                                                   int h = QQP.getHeight() - (cnt-1)*60;
                                                 if(h < 0) h=60;
                                                   if(cnt >= 1)
                                                     QQP.getComponent(cnt-1).setPreferredSize(new Dimension(250, h));
                                                   
                                                   cnt = QQP.getComponentCount();
                                                   if(cnt*60 <= QQPheight)
                                                       QQP.setPreferredSize(new Dimension(QQP.getWidth(), QQPheight));
                                                   else 
                                                       QQP.setPreferredSize(new Dimension(QQP.getWidth(), cnt*60));
                                                   QQP.updateUI();
                                                   
                                                   String NameAndIP = lab.getText();
                                                  String ip = NameAndIP.substring(NameAndIP.indexOf(':') + 1);
                                                   QQset.remove(ip);
                                                   QQFrame fm = QQmap.get(ip);
                                                   if(fm != null) fm.dispose();
                                                   nameToIP.remove(NameAndIP.substring(0, NameAndIP.indexOf(':')));
                                                   QQmap.remove(ip);
                                               }
                                        }
                                  });
                                   
                                   JMenuItem edit = new JMenuItem("编辑");
                                   edit.addActionListener(new ActionListener() {
                                    
                                      public void actionPerformed(ActionEvent e) {
                                            //得到之前的数据!
                                            String content = lab.getText();
                                            String oldName = content.substring(0, content.indexOf(':'));
                                            String oldIP = content.substring(content.indexOf(':')+1);
                                            //从新设置到文本框中
                                            InputDialog id = new InputDialog(oldIP, oldName, true);
                                            if(id.key == InputDialog.CANCELBTN || id.key== 0) return;
                                            lab.setText(id.NAME + ":" + id.IP);
                                            
                                            QQFrame fm = QQmap.get(oldIP);
                                            if(fm != null){
                                                try{
                                                    fm.setSendIAD(id.IP);
                                                    
                                                    QQmap.put(id.IP, fm);
                                                    fm.setTitle(id.NAME);
                                                    QQmap.remove(oldIP);
                                                    QQset.remove(oldIP);
                                                    QQset.add(id.IP);
                                                    nameToIP.remove(oldName);
                                                    nameToIP.put(id.NAME, id.IP);
                                                    
                                                }catch(RuntimeException ex){
                                                    JOptionPane.showMessageDialog(null, ex.getMessage(), "修改之后的IP!", JOptionPane.OK_OPTION);
                                                }
                                            }
                                        }
                                  });
                                   edit.setFont(new Font("华文行楷", Font.ITALIC, 20));
                                   edit.setForeground(new Color(255, 0, 255));
                                   pm.setBorderPainted(true);
                                   pm.setBackground(new Color(125, 0, 125));
                                   pm.add(del);  pm.add(edit);
                                   pm.show(lab, e.getX(), e.getY());
                              }
                         }
                         
                 });
            }
            
            //内部类,用来访问Frame中的数据成员
            class InputDialog extends Dialog{
                private JLabel ipLabel = new JLabel("IP地址:");
                private JLabel nameLabel = new JLabel("姓名:");
                private JButton okBtn = new JButton("确定");
                private JButton cleBtn = new JButton("取消");
                private JTextField ipText = new JTextField(20);
                private JTextField nameText = new JTextField(20);
                private static final int OKBTN = 1;
                private static final int CANCELBTN = 2;
                private int key = 0;
                private String IP = null, NAME = null; 
                private boolean flag = false;
                void initDialog(){
                    JPanel p = null;
                    setModal(true);
                    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
                    
                    add(p = new JPanel());
                    p.setLayout(new FlowLayout(FlowLayout.CENTER));
                    ipLabel.setPreferredSize(new Dimension(50, 12));
                    p.add(ipLabel); p.add(ipText);
                    
                    
                    add(p = new JPanel());
                    p.setLayout(new FlowLayout(FlowLayout.CENTER));
                    nameLabel.setPreferredSize(new Dimension(50, 12));
                    p.add(nameLabel); p.add(nameText);
                    
                    add(p = new JPanel());
                    p.setLayout(new FlowLayout(FlowLayout.CENTER));
                    p.add(okBtn); p.add(cleBtn);
                    
                    addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                                 key = 0;
                                 dispose();
                            }
                    });
                    
                    addMouseListener(new MouseAdapter() {
                            public void mouseClicked(MouseEvent e) {
                                 requestFocus();
                            }
                    });
                    
                    okBtn.addMouseListener(new MouseAdapter() {
                            public void mouseClicked(MouseEvent e) {
                                 key = InputDialog.OKBTN;
                                 if("".equals(ipText.getText()) || "".equals(nameText.getText()) || !checkIP(ipText.getText()) )
                                         JOptionPane.showMessageDialog(null, "信息不全或者IP填写错误!");
                                 else{
                                     String ip = ipText.getText();
                                     if(!flag && QQset.contains(ip)){
                                         JOptionPane.showMessageDialog(null, "好友已存在!", "QQ好友", JOptionPane.OK_OPTION);
                                         return ;
                                     }
                                     IP = ipText.getText();
                                     NAME = nameText.getText();
                                     dispose();
                                 }
                            }
                    });
                    
                    cleBtn.addMouseListener(new MouseAdapter() {
                            public void mouseClicked(MouseEvent e) {
                                key = InputDialog.CANCELBTN;
                                dispose();
                            }
                    });
                    setSize(300, 200);
                    setLocation(200, 200);
                    setVisible(true);
                }
                
                public InputDialog(String ip, String name){
                    super(new Frame());
                    ipText.setText(ip);
                    nameText.setText(name);
                    initDialog();
                }
                
                public InputDialog(String ip, String name, boolean flag){
                    super(new Frame());
                    ipText.setText(ip);
                    nameText.setText(name);
                    this.flag = flag;
                    initDialog();
                }
                
                public InputDialog(){
                    super(new Frame());
                    initDialog();
                }
                
                public boolean checkIP(String ip){
                    int i, begin = 0, end;
                    for(i = 1; i <= 4; ++i){
                        end = ip.indexOf('.', begin);
                        if(end == -1) return false;
                        int p = Integer.valueOf(ip.substring(begin, end));
                        if(p < 0 || p > 255)  return false;
                    }
                    return true;
                }
                
                public String getIPText(){
                    return IP;
                }
                
                public String getNameText(){
                    return NAME;
                }
                
            }
            
            
            private static ServerSocketQQ ss = null;
            private static QQReceive qr = null;
            
            public static void main(String[] args){
    
                 ss = new ServerSocketQQ();
                 new Thread(ss).start();
                 if(ServerSocketQQ.getPort() < 1) return;
                 
                 qr = new QQReceive();
                 new Thread(qr).start();
                 if(QQReceive.getPort() < 1)  return ;
                 
                new QQDialog();
            }
    }
    View Code
    package testFour;
    
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.TextArea;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.SocketAddress;
    import java.net.UnknownHostException;
    import java.util.Calendar;
    import java.util.Iterator;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    import javax.imageio.ImageReader;
    import javax.imageio.stream.ImageInputStream;
    import javax.swing.BoxLayout;
    import javax.swing.JButton;
    import javax.swing.JFileChooser;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.filechooser.FileFilter;
    
    
    
    public class QQFrame extends Frame{
         private TextArea taSend = new TextArea();
         private JTextPane taReceive = new JTextPane();
         private JScrollPane p = new JScrollPane(taReceive);
         private JPanel pSend = new JPanel();
         private JPanel pReceive = new JPanel();
         private Label laSend = new Label("发送端.....");
         private Label laReceive = new Label("接收端.....");
         private JButton FileBtn = new JButton("传输文件");
         private JButton PicuterBtn = new JButton("发送图片");
         private InetAddress sendIAD = null;//当前窗口所对应的好友所在机器的IP对象
         private String QQname = null;//该对话框所对应的好友的姓名
         private Socket st =null;
         private String text;
         private DatagramSocket ds = null;
        
         public QQFrame(String name, byte[] ipBuf) throws RuntimeException{
             try {
                sendIAD = InetAddress.getByAddress(ipBuf);
             } catch (UnknownHostException e3) {
                throw new RuntimeException("IP错误(不存在或无发链接)!");
             }
             
             ds = QQReceive.getUdpSocket();
             if(ds == null)  throw new RuntimeException("udp Socket出错!");
             
             QQname = name;
             text = "";
             setSize(600, 600);
             setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
             pSend.setLayout(new FlowLayout(FlowLayout.LEFT));
             pSend.add(laSend);
             pSend.add(FileBtn);
             pSend.add(PicuterBtn);
             pReceive.setLayout(new FlowLayout(FlowLayout.LEFT));
             pReceive.add(laReceive);
             
             taReceive.setForeground(new Color(255, 0, 255));
             add(pReceive);
             add(p);
             add(pSend);
             add(taSend);
             setTitle("我的好友 " + QQname);
             
             
             taSend.setPreferredSize(new Dimension(0, 200));
             taReceive.setPreferredSize(new Dimension(0, 400));
             
             taSend.setFont(new Font("仿宋", Font.PLAIN, 20));
             taReceive.setFont(new Font("黑体", Font.PLAIN, 25));
             
             taReceive.setEditable(false);//不能进行文本的编辑,但是可以进行访问
             
             taSend.addKeyListener(new KeyAdapter() {
                
                 public void keyPressed(KeyEvent e) {
                    if(e.getKeyCode() == KeyEvent.VK_ENTER){
                         text = taSend.getText();
                         if(text == null) return;
                         text += "
    
    ";
                         byte[] bt = text.getBytes();
                         DatagramPacket dp = null;
                         try {
                             //向指定的ip和端口发送数据~!
                             //先说明一下数据是谁发送过来的!
                             byte[] ip = InetAddress.getLocalHost().getHostAddress().getBytes();
                             dp = new DatagramPacket(ip, ip.length, sendIAD, QQReceive.getPort());
                             ds.send(dp);
                             
                             //这里主要是因为多可数据报包发送时会产生丢包的情况...所以暂停一段时间!
                             try {
                                Thread.sleep(100);
                             } catch (InterruptedException e1) {
                             }
                             
                             dp = new DatagramPacket("PARAGRAPH".getBytes(), "PARAGRAPH".getBytes().length, sendIAD, QQReceive.getPort());
                             ds.send(dp);
                             
                             try {
                                    Thread.sleep(100);
                             } catch (InterruptedException e1) {
                                 
                             }
                             
                             dp = new DatagramPacket(bt, bt.length, sendIAD, QQReceive.getPort());
                             ds.send(dp);
                         } catch (IOException e1) {
                            e1.printStackTrace();
                         }
                         
                         synchronized(QQ.class){//发送端向接收窗口添加数据时 要 和 接收端向接收窗口添加数据时同步!
                             byte[] x = null;
                             try {
                                x = new String(InetAddress.getLocalHost().getHostName() + " : ").getBytes();
                             } catch (UnknownHostException e1) {
                                e1.printStackTrace();
                             }
                             QQ.setTextPane(taReceive, x, x.length, QQ.PARAGRAPH, QQ.SEND);
                             x = text.getBytes();
                             QQ.setTextPane(taReceive, x, x.length, QQ.PARAGRAPH, QQ.SEND*3);
                             taSend.requestFocus();
                         }
                         
                         taSend.setText("");//发送端清空
                         e.consume();//不让这个回车字符在输入端显示!
                         return ;
                    }
                }
                 
             });
             
             addWindowListener(new WindowAdapter() {
    
                public void windowClosing(WindowEvent e) {
                    Map<String, QQFrame>mp = QQDialog.getMap();
                    mp.remove(sendIAD.getHostAddress());
                    dispose();
                }
                 
             });
             
             FileBtn.addMouseListener(new MouseAdapter() {//文件传输
                    public void mouseClicked(MouseEvent e) {
                         JFileChooser jfc = new JFileChooser();
                         jfc.showOpenDialog(null);
                         File fl = jfc.getSelectedFile();
                         if(fl == null) return ;
                         try {
                            st =  new Socket();//尝试连接对方
                            st.connect(new InetSocketAddress(sendIAD, ServerSocketQQ.getPort()), 1000);
                         } catch (IOException e2) {
                            st = null;
                            JOptionPane.showMessageDialog(null, "请求超时或连接错误!", "ServerSocket", JOptionPane.OK_CANCEL_OPTION);
                         }
                         if(st != null){
                            try {
                                byte[] bt = new byte[1024];
                                InputStream is = st.getInputStream(); 
                                OutputStream os = st.getOutputStream();
                                //先说明一下是谁发送过来的!
                                byte[] ip = InetAddress.getLocalHost().getHostAddress().getBytes();
                                os.write(ip);
                                os.flush();
                                
                                try {
                                    Thread.sleep(100);
                                } catch (InterruptedException e1) {
                                 
                                }
                                
                                //向对方首先发送文件名, 然后发送文件内容!
                                os.write(fl.getName().getBytes());
                                os.flush();
                                
                                try {
                                    Thread.sleep(100);
                                } catch (InterruptedException e1) {
                                 
                                }
                                
                                int len;
                                InputStream fis = new FileInputStream(fl);
                                while( (len = fis.read(bt)) != -1){
                                    os.write(bt, 0, len);
                                    os.flush();
                                }
                                bt = new String(Calendar.getInstance().getTime().toString() + ":文件已传输!").getBytes();
                                QQ.setTextPane(taReceive, bt, bt.length, QQ.FILE, QQ.FILEX);
                                st.shutdownOutput();//输出流结束,并标记一下,使服务端知道客户端输出已经结束了!
                                st.close();
                            
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            }
                         }
                    }
             });
             
             PicuterBtn.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        JFileChooser jfc = new JFileChooser();
                        jfc.setFileFilter(new PicuterFilter());//设置当前的文件过滤器!
                        jfc.setAcceptAllFileFilterUsed(false);//设置所有文件过滤器不使用!
                        //jfc.addChoosableFileFilter(new Filter());
                        jfc.showOpenDialog(null);
                        
                       //将输入流按照下面方式处理, 根据Iterator<ImageReader> itImage是否能
                       //成功的返回一个ImageReader对象确认该流文件是否是一个图片文件!
                       //并ImageReader类中的getFormatName()得到文件的格式!
                       //通过最后可以通过ImageIcon的byte[]构造函数建立ImageIcon对象!
                       //最后将图片显示在面板上!
                        File fl = jfc.getSelectedFile();
                        if(fl == null) return ;
                        try{
                                 InputStream is = new FileInputStream(fl);
                                 ImageInputStream iis = ImageIO.createImageInputStream(is);
                                 Iterator<ImageReader> itImage = ImageIO.getImageReaders(iis);
                                 if(itImage.hasNext()){
                                      ImageReader reader = itImage.next();
                                      byte[] imageByte = new byte[1024*64];
                                      int len = iis.read(imageByte);
                                      if(len > 64 * 1000){
                                          JOptionPane.showMessageDialog(new Frame(), "图片过大!请采用文件传输!");
                                          return ;
                                      }
                                      DatagramPacket dp = null;
                                      //先说明一下数据是谁发送过来的!
                                      byte[] ip = InetAddress.getLocalHost().getHostAddress().getBytes();
                                      dp = new DatagramPacket(ip, ip.length, sendIAD, QQReceive.getPort());
                                      ds.send(dp);
                                      
                                      try {
                                            Thread.sleep(100);
                                      } catch (InterruptedException e1) {
                                      }
                                      
                                      dp = new DatagramPacket("PICUTER".getBytes(), "PICUTER".getBytes().length, sendIAD, QQReceive.getPort());
                                      ds.send(dp);
                                      
                                      try {
                                            Thread.sleep(100);
                                      } catch (InterruptedException e1) {
                                      }
                                      
                                      dp = new DatagramPacket(imageByte, len, sendIAD, QQReceive.getPort());
                                      ds.send(dp);
                                      synchronized(QQ.class){
                                          byte[] name = null;
                                          name = new String(InetAddress.getLocalHost().getHostName() + " : ").getBytes();
                                          QQ.setTextPane(taReceive, name, name.length, QQ.PARAGRAPH, QQ.SEND);
                                          QQ.setTextPane(taReceive, imageByte, len, QQ.PICUTER, 0);
                                      }
                                 }
                                 else throw new NoPicuterException("不是一张图片!");
                        }catch(IOException ex){
                            ex.printStackTrace();
                        }
                    }
             });
             
             setVisible(true);
         }
         
         public void setSendIAD(String ip) throws RuntimeException{
             String[] ipStr = ip.split("\.");//将字符串中的数字分离
             byte[] ipBuf = new byte[4];//存储IP的byte数组
             for(int i = 0; i < 4; i++){
                 ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);
             }
             try {
                 sendIAD = InetAddress.getByAddress(ipBuf);
              } catch (UnknownHostException e3) {
                 throw new RuntimeException("IP错误(不存在或无发链接)!");
              }
         }
         
         public DatagramSocket getDs(){
             return ds;
         }
         
         public JTextPane getReceive(){
             return taReceive;
         }
         
    }
    
    class PicuterFilter extends FileFilter {
         
        public boolean accept(File file){
               return(file.isDirectory() || file.getName().endsWith(".gif") 
                      || file.getName().endsWith(".png") || file.getName().endsWith(".bmp")
                      || file.getName().endsWith(".jpg") );
               /* 返回要显示的文件类型 */
               /*
                *   File.isDirectory()测试此抽象路径名表示的文件是否是一个目录
               */
          }
          
          public String getDescription() {
              return("Picuter Files(*.gif, *.png, *.jpg, *.bmp)");                  //返回显示文件类型的描述
          }
    }
    
    class NoPicuterException extends IOException{
        public NoPicuterException(String x){
            super(x);
        }
    }
    View Code
    package testFour;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    import java.util.Map;
    import java.util.Set;
    
    import javax.swing.JOptionPane;
    
    public class QQReceive implements Runnable{
        private QQFrame fm = null;
        private static DatagramSocket ds = null;
        private static int port = 10101;
        private boolean flag = true;
        
        public void setFlag(){
            if(ds != null)
                ds.close();
            flag = false;
        }
        public QQReceive(){
            try {
                //建立udp通信方式
                ds = new DatagramSocket(port);
             } catch (SocketException e1) {
                 port = -1;
                 JOptionPane.showMessageDialog(null, "DatagramSocket端口绑定错误!", "绑定错误", JOptionPane.OK_CANCEL_OPTION);
            }
        }
        
        public static DatagramSocket getUdpSocket(){
            return ds;
        } 
        
        public static int getPort(){
            return port;
        }
        
        public DatagramSocket getDS(){
            return ds;
        }
        
        public void run(){
            if(ds == null) return ;
            byte[] bt = new byte[10024*10]; 
            DatagramPacket dp = new DatagramPacket(bt, bt.length); 
            while(flag){
                int flagx = 0;
                try {
                        //ds.setReceiveBufferSize(size);
                        ds.receive(dp);
                        String ip = new String(dp.getData(), 0, dp.getLength());
                        
                        ds.receive(dp);
                        String tag = new String(dp.getData(), 0, dp.getLength());
                        
                        ds.receive(dp);
                        
                        Map<String, QQFrame>mp = QQDialog.getMap();
                        Set<String>  set = QQDialog.getSet();
                        fm = mp.get(ip);
                        System.out.println(ip);
                        if(set.contains(ip) && fm == null){//如果存在该好友,但是不存在对应的对话窗口
                             //自动产生对话窗口
                             Map<String, String> nameToIP = QQDialog.getNameToIP();
                             String[] ipStr = ip.split("\.");//将字符串中的数字分离
                             byte[] ipBuf = new byte[4];//存储IP的byte数组
                             for(int i = 0; i < 4; i++){
                                 ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);
                             }
                             String name = null;
                             for(String ss : nameToIP.keySet())
                                 if( ip.equals(nameToIP.get(ss)) ){
                                       name = ss;
                                       break;
                                 }
                             fm = new QQFrame(name, ipBuf);
                        }else if(fm != null){
                             fm.requestFocus();
                        }
                        
                        if( tag.equals("FILE") )
                            flagx = QQ.FILE;
                        else if( tag.equals("PICUTER"))
                            flagx = QQ.PICUTER;
                        else if( tag.equals("PARAGRAPH"))
                            flagx = QQ.PARAGRAPH;
                    
                } catch (IOException e) {
                    e.printStackTrace();
                }
                synchronized(QQ.class){
                    if(fm == null) continue;
                    byte[] x = new String(dp.getAddress().getHostName() + " : ").getBytes();
                    QQ.setTextPane(fm.getReceive(), x, x.length, QQ.PARAGRAPH, QQ.RECEIVE);
                    QQ.setTextPane(fm.getReceive(), dp.getData(), dp.getLength(), flagx, QQ.RECEIVE*3);
                }
            }
        }
    }
    View Code
    package testFour;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Calendar;
    import java.util.Map;
    import java.util.Set;
    
    import javax.swing.JOptionPane;
    
    public class ServerSocketQQ implements Runnable{
        private ServerSocket sst = null;
        private Socket st = null;
        private static int port = 10100;
        private boolean flag = true;
        
        public void setFlag(){
            if(sst != null)
                try {
                    sst.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            flag = false;
        }
        
        public static int getPort(){
            return port;
        }
        
        public ServerSocketQQ(){
            //建立服务端
            try {
                sst = new ServerSocket(port);
            } catch (IOException e) {
                port = -1;
                JOptionPane.showMessageDialog(null, "ServerSocket端口绑定错误!", "绑定错误", JOptionPane.OK_CANCEL_OPTION);
            }
            
        }
        
        public void run(){
            byte[] bt = null;
            int len = 0;
            if(sst == null)  return ;
            while(true){
                try{
                    //侦听并接受到此服务套接字的连接。此方法在进行连接之前一直阻塞。 创建新套接字 
                    st = sst.accept();
                    //得到客户端传输过来的流
                    InputStream is = st.getInputStream();
                    OutputStream os  = st.getOutputStream();
                    bt = new byte[1024];
                    
                    len = is.read(bt);
                    String name = new String(bt, 0, len);
                    QQFrame fm = null;
                    Map<String, QQFrame>mp = QQDialog.getMap();
                    Set<String>  set = QQDialog.getSet();
                    fm = mp.get(name);
                    if(set.contains(name) && fm == null){//如果存在该好友,但是不存在对应的对话窗口
                         //自动产生对话窗口
                         Map<String, String> nameToIP = QQDialog.getNameToIP();
                         fm = new QQFrame(name, nameToIP.get(name).getBytes());
                    }
                    if(fm == null){//对方不存在该好友!
                        st.close();
                        continue;
                    }
                    
                    len = is.read(bt);
                    String fileName = new String(bt, 0, len);
                    
                    int choose = JOptionPane.showConfirmDialog(null, "接受或不接受", "文件传输提示", JOptionPane.YES_NO_OPTION);
                    if(choose == JOptionPane.NO_OPTION){
                        bt = new String(Calendar.getInstance().getTime().toString() + ":文件接受失败!").getBytes();
                        QQ.setTextPane(fm.getReceive(), bt, bt.length, QQ.FILE, QQ.FILEX);
                        st.close();
                        continue;
                    }
                    FileOutputStream fos = new FileOutputStream( new File(fileName) );
                    while( (len = is.read(bt)) != -1 ){//先将流文件变成byte[], 然后利用套接字的输出流发送给客户端
                         fos.write(bt);
                         fos.flush();
                    }
                    bt = new String(Calendar.getInstance().getTime().toString() + ":文件接受成功!").getBytes();
                    QQ.setTextPane(fm.getReceive(), bt, bt.length, QQ.FILE, QQ.FILEX);
                    st.close();
               }catch(IOException e){
                   e.printStackTrace();
               }
            }
         }
        
    }
    View Code
  • 相关阅读:
    prometheus监控示例
    es索引管理工具-curator
    GlusterFS分布式文件系统的使用
    Django的admin相关
    Django的form表单
    Django-models & QuerySet API
    python-css基础知识
    PXC 避免加入集群时发生SST
    ERROR 1682 (HY000)
    pxc群集搭建
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/4004368.html
Copyright © 2011-2022 走看看