首页 > 代码库 > java模拟一个简单的QQ

java模拟一个简单的QQ

 效果图:

 

      

  1 package testFour;  2   3 import java.awt.Color;  4 import java.awt.Dimension;  5 import java.awt.FontMetrics;  6 import java.awt.Graphics;  7 import java.io.ByteArrayInputStream;  8 import java.io.IOException;  9 import java.io.InputStream; 10 import java.net.BindException; 11 import java.net.ServerSocket; 12 import java.util.Iterator; 13  14 import javax.imageio.ImageIO; 15 import javax.imageio.ImageReader; 16 import javax.imageio.stream.ImageInputStream; 17 import javax.swing.ImageIcon; 18 import javax.swing.JLabel; 19 import javax.swing.JPanel; 20 import javax.swing.JTextPane; 21 import javax.swing.text.BadLocationException; 22 import javax.swing.text.Document; 23 import javax.swing.text.SimpleAttributeSet; 24 import javax.swing.text.StyleConstants; 25  26 public class QQ { 27     public static final int PICUTER = 1;  28     public static final int FILE = 2;  29     public static final int PARAGRAPH = 3;  30     public static final int SEND = 1;  31     public static final int RECEIVE = 2;  32     public static final int FILEX = 3; 33      34     public static int getUnusedPort() throws BindException{ 35         int port; 36         for(port = 10000 ; port <= 65535; ++port){ 37             ServerSocket ss = null;  38             try { 39                 ss = new ServerSocket(port); 40             } catch (IOException e) { 41                 e.printStackTrace(); 42             } 43             if(ss != null) break; 44         } 45         if(port > 65535) 46             throw new BindException("没有可用的端口!"); 47         return port; 48     } 49      50     public synchronized static void setTextPane(JTextPane tp, byte[] bt, int len, int flag, int tag){ 51          ImageIcon myIcon = null; 52          if(tag == SEND) 53              myIcon = new ImageIcon("ff.jpg"); 54          else if(tag == RECEIVE) 55              myIcon = new ImageIcon("gg.jpg"); 56          else if(tag == FILEX) 57              myIcon = new ImageIcon("kk.jpg"); 58           59          SimpleAttributeSet set = new SimpleAttributeSet(); 60          Document doc = tp.getStyledDocument(); 61           62          if(tag == SEND || tag == RECEIVE){ 63               tp.setCaretPosition(doc.getLength()); 64               JLabel fileLabel = new JLabel("", myIcon, JLabel.CENTER); 65               tp.insertComponent(fileLabel); 66          } 67           68          if(flag == PARAGRAPH){ 69              FontMetrics fm = tp.getFontMetrics(tp.getFont()); 70              int paneWidth = tp.getWidth(); 71              String text = new String(bt, 0, len); 72               73              if( tag/3 == SEND ){ 74                  StyleConstants.setForeground(set, new Color(0,255,0));//设置文字颜色 75                  StyleConstants.setFontSize(set, 15);//设置字体大小 76              } 77              else if( tag/3 == RECEIVE){ 78                  StyleConstants.setForeground(set, new Color(0,0,0));//设置文字颜色 79                  StyleConstants.setFontSize(set, 15);//设置字体大小 80              } 81               82              try 83               { 84                   for(int i = 0, cnt = 0; i < text.length(); ++i){ 85                       if((cnt += fm.charWidth(text.charAt(i))) >= paneWidth){ 86                           cnt = 0; 87                           doc.insertString(doc.getLength(), "\n", set); 88                           continue; 89                       } 90                       doc.insertString(doc.getLength(), String.valueOf(text.charAt(i)), set); 91                   } 92                   doc.insertString(doc.getLength(), "\n", set); 93                    94                   tp.setCaretPosition(doc.getLength());//最简单的设置滚动条的位置到最后输出文本的地方 95                                                          //就是将JTextPane中的插入符的位置移动到文本的末端! 96               } 97               catch (BadLocationException e) 98               { 99               }100              101          } else if(flag == PICUTER) {102             103              try{104                      InputStream is = new ByteArrayInputStream(bt, 0, len);105                      ImageInputStream iis = ImageIO.createImageInputStream(is);106                      Iterator<ImageReader> itImage = ImageIO.getImageReaders(iis);107                      if(itImage.hasNext()){108                          ImageReader reader = itImage.next();109                          ImageIcon ii = new ImageIcon( bt, reader.getFormatName() );110                          tp.setCaretPosition( doc.getLength() );111                          tp.insertComponent( new PicuterPanel(ii) );112                          doc.insertString(doc.getLength(), "\n", set);113                      }114              }catch(IOException ex){115                      ex.printStackTrace();116              }catch(BadLocationException e1){117                    118              }119              120          } else if(flag == FILE) {121               try{122                   tp.setCaretPosition(doc.getLength());123                   JLabel fileLabel = new JLabel(new String(bt, 0, len), myIcon, JLabel.LEFT);124                   tp.insertComponent(fileLabel);125                   doc.insertString(doc.getLength(), "\n", set);126               }catch (BadLocationException e) {127                   e.printStackTrace();128             }129          }130     }131 }132 133 class PicuterPanel extends JPanel{134     private ImageIcon ii;135     public PicuterPanel(ImageIcon ii){136         this.ii = ii;137         setPreferredSize(new Dimension(200, 300));138         setBackground(new Color(255, 255, 255));139     }140     141     protected void paintComponent(Graphics g) {142           super.paintComponent(g);143           g.drawImage(ii.getImage(), 0, 0, 200, 300, 0, 0, ii.getIconWidth(), ii.getIconHeight(), this);144     }145 }
View Code
  1 package testFour;  2   3 import java.awt.BorderLayout;  4 import java.awt.Color;  5 import java.awt.Dialog;  6 import java.awt.Dimension;  7 import java.awt.FlowLayout;  8 import java.awt.Font;  9 import java.awt.Frame; 10 import java.awt.Point; 11 import java.awt.event.ActionEvent; 12 import java.awt.event.ActionListener; 13 import java.awt.event.MouseAdapter; 14 import java.awt.event.MouseEvent; 15 import java.awt.event.WindowAdapter; 16 import java.awt.event.WindowEvent; 17 import java.net.InetAddress; 18 import java.net.UnknownHostException; 19 import java.util.Map; 20 import java.util.Random; 21 import java.util.Set; 22 import java.util.TreeMap; 23 import java.util.TreeSet; 24  25 import javax.print.attribute.standard.Severity; 26 import javax.swing.BoxLayout; 27 import javax.swing.ImageIcon; 28 import javax.swing.JButton; 29 import javax.swing.JLabel; 30 import javax.swing.JMenuItem; 31 import javax.swing.JOptionPane; 32 import javax.swing.JPanel; 33 import javax.swing.JPopupMenu; 34 import javax.swing.JScrollBar; 35 import javax.swing.JScrollPane; 36 import javax.swing.JTextField; 37 import javax.swing.ScrollPaneConstants; 38  39  40  41 public class QQDialog extends Frame{ 42         private JPanel QQP = new JPanel(); 43         private JButton myFriend = new JButton("QQ好友>>"); 44         private JPanel funP = new JPanel(); 45         private JButton add = new JButton("添加好友"); 46         private JButton serach = new JButton("查询好友"); 47         private JPanel pp = new JPanel(); 48         private JPanel tmp = null; 49         private final int QQPheight = 397; 50         private JScrollPane jsp = new JScrollPane(QQP); 51         private static Set<String>QQset;//姓名的集合 52         private static Map<String, QQFrame>QQmap;//姓名到对通信窗口的映射 53         private static Map<String, byte[]>nameToIP;//姓名到IP的映射 54         ImageIcon[] ii = new ImageIcon[3]; 55          56         public static Map<String, QQFrame> getMap(){ 57             return QQmap; 58         } 59          60         public static Set<String> getSet(){ 61             return QQset; 62         } 63          64         public static Map<String, byte[]> getNameToIP(){ 65             return nameToIP; 66         } 67          68         public QQDialog(){ 69              70             QQset = new TreeSet<String>(); 71             QQmap = new TreeMap<String, QQFrame>(); 72             nameToIP = new TreeMap<String, byte[]>(); 73              74             ii[0] = new ImageIcon("ff.jpg"); 75             ii[1] = new ImageIcon("gg.jpg"); 76             ii[2] = new ImageIcon("kk.jpg"); 77             setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 78             jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 79             jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 80             pp.add(jsp); 81             pp.setLayout(new BoxLayout(pp, BoxLayout.Y_AXIS)); 82             QQP.setLayout(new BoxLayout(QQP, BoxLayout.Y_AXIS)); 83             JPanel pmyFriend = new JPanel(); 84             pmyFriend.setLayout(new BorderLayout()); 85             pmyFriend.add(myFriend, "Center"); 86             pmyFriend.setPreferredSize(new Dimension(300, 20)); 87             add(pmyFriend); 88             pp.setPreferredSize(new Dimension(300, 400)); 89             add(pp); 90             add(funP); 91              92             JLabel myself = null; 93             try { 94                 myself = new JLabel(InetAddress.getLocalHost().getHostName() + ":" + InetAddress.getLocalHost().getHostAddress()); 95             } catch (UnknownHostException e) { 96                 e.printStackTrace(); 97             } 98             addLabelListener(myself); 99             myself.setIcon(new ImageIcon("ff.jpg"));100             101             tmp = new JPanel();102             tmp.setLayout(new FlowLayout(FlowLayout.CENTER));103             tmp.setBackground(new Color(255, 0, 255));104             tmp.setPreferredSize(new Dimension(250, 60));105             tmp.add(myself);106             QQP.add(tmp);107             funP.setLayout(new FlowLayout(FlowLayout.CENTER));108             funP.add(add);109             funP.add(serach);110             111             myFriend.addMouseListener(new MouseAdapter() {112                 113                     public void mouseClicked(MouseEvent e) {//将好友面板进行收缩的效果!114                         if("QQ好友>>".equals(myFriend.getText())){115                             QQP.setVisible(false);116                             myFriend.setText("QQ好友<<");117                         }118                         else{119                             QQP.setVisible(true);120                             myFriend.setText("QQ好友>>");121                         }122                     }123 124             });125             126             add.addMouseListener(new MouseAdapter() {127                     public void mouseClicked(MouseEvent e) {128                         InputDialog dlg = new InputDialog();129                         if(dlg.key == InputDialog.CANCELBTN || dlg.key== 0) return;130                         Random rd = new Random();131                         int index = Math.abs(rd.nextInt()) % 3;132                         JLabel ll = new JLabel(dlg.getNameText() + ":" + dlg.getIPText(), ii[index], JLabel.LEFT);133                         tmp = new JPanel();134                         tmp.setLayout(new FlowLayout(FlowLayout.CENTER));135                         tmp.setBackground(new Color(255, 0, 255));136                         137                         /*138                          *  BoxLayout布局简直是蛋疼的要命,一个面板X是BoxLayout布局,如果该面板添加一个面板Y的话139                          *  那么Y就会填充X面板!如果在添加一个面板Z, 那么Y, Z就会一起布满X面板!但是可以设置Y,Z面板140                          *  的比例! 如果X添加的是一个按钮或者标签时,还不能控制其大小.....无语了!141                          *  142                          *  下面的我的做法将标签添加到面板tmp中,然后再将tmp添加中QQP面板中!这样就可以控制标签的大小了!143                          *  再添加新的面板的时候,要设置一下之前面板的PreferredSize!保证每一个标签的距离适中!144                          *  也就是保证所有的添加的面板的高度之和 == QQP.getHeight();145                          * */146                         int cnt = QQP.getComponentCount();//显示QQ好友的个数!147                         if(cnt >= 1)148                             QQP.getComponent(cnt-1).setPreferredSize(new Dimension(250, 60));149                         int h = QQP.getHeight() - cnt*60;150                         if(h < 0) h=60;151                         tmp.setPreferredSize(new Dimension(250, h));152                         tmp.add(ll);153                         QQP.add(tmp);154                         QQP.add(tmp);155                         addLabelListener(ll);//给标签添加监听器156                         JScrollBar jsb = jsp.getVerticalScrollBar();157                         QQP.updateUI();//利用当前外观的值重置 UI 属性。 也可以保证滚动条随时的更新158                         //终于搞好了,将垂直滚动条自动的移动到最低端159                         jsp.getViewport().setViewPosition(new Point(0, jsp.getVerticalScrollBar().getMaximum()));160                     }161             });162             163             serach.addMouseListener(new MouseAdapter() {164                     public void mouseClicked(MouseEvent e) {165                           String name = JOptionPane.showInputDialog(null, "好友姓名", "好友查询", JOptionPane.OK_OPTION);166                           if(name == null)  return ;167                           if(!QQset.contains(name))168                                   JOptionPane.showMessageDialog(null, "好友不存在!", "查询结果", JOptionPane.OK_OPTION);169                           else{170                               QQFrame fm = QQmap.get(name);171                               if(fm == null){172                                   try{173                                         fm = new QQFrame(name, nameToIP.get(name));174                                     }catch(RuntimeException ex){175                                         JOptionPane.showMessageDialog(null, ex.getMessage(), "Socket错误!", JOptionPane.OK_CANCEL_OPTION);176                                         return ;177                                     }178                                   QQmap.put(name, fm);179                               }180                               else fm.requestFocus();181                           }182                     }183             });184             185             addWindowListener(new WindowAdapter() {186                     public void windowClosing(WindowEvent e) {187                         if(qr == null) System.out.println("hehe");188                         qr.setFlag();//udp服务线程停止189                         ss.setFlag();//tcp服务线程停止190                         System.exit(0);191                     }192             });193             194             QQP.setBackground(new Color(255, 0, 255));195             funP.setBackground(new Color(255, 255, 0));196             setResizable(false);197             setSize(300, 500);198             setLocation(500, 200);199             setVisible(true);200         }201         202         203         public void addLabelListener(final JLabel lab){204              lab.setOpaque(true);205              lab.setBackground(new Color(255, 255, 255));206              lab.setPreferredSize(new Dimension(250, 55));207              208              String NameAndIP = lab.getText();209               String name = NameAndIP.substring(0, NameAndIP.indexOf(‘:‘));210               String ip = NameAndIP.substring(NameAndIP.indexOf(‘:‘) + 1, NameAndIP.length());211             212               String[] ipStr = ip.split("\\.");//将字符串中的数字分离213              byte[] ipBuf = new byte[4];//存储IP的byte数组214              for(int i = 0; i < 4; i++){215                  ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);216              }217              nameToIP.put(name, ipBuf);218              QQset.add(name);219              220              lab.addMouseListener(new MouseAdapter() {221                      Color oldC = lab.getBackground();222                      public void mouseEntered(MouseEvent e) {223                           lab.setBackground(new Color(0, 255, 0));224                      }225                      226                      public void mouseExited(MouseEvent e) {227                           lab.setBackground(oldC);228                      }229                      230                      public void mouseClicked(MouseEvent e) {231                           //打开通信窗口232                           if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2){233                                  String NameAndIP = lab.getText();234                                  String name = NameAndIP.substring(0, NameAndIP.indexOf(‘:‘));235                                  if(QQmap.get(name) != null){//这个好友的窗口已经存在!236                                     QQmap.get(name).requestFocus();237                                     return ;238                                  }239                                  QQFrame fm = null;240                                 try{241                                     fm = new QQFrame(name, nameToIP.get(name));242                                 }catch(RuntimeException ex){243                                     JOptionPane.showMessageDialog(null, ex.getMessage(), "Socket错误!", JOptionPane.OK_CANCEL_OPTION);244                                     return ;245                                 }246                                  247                                  QQmap.put(name, fm);//name 和 窗口的映射!248                           }249                           else if(e.getButton() == MouseEvent.BUTTON3){250                                JPopupMenu pm = new JPopupMenu("胡峻峥");251                                JMenuItem del = new JMenuItem("删除");252                                del.setFont(new Font("华文行楷", Font.ITALIC, 20));253                                del.setForeground(new Color(255, 0, 0));254                                del.addActionListener(new ActionListener() {255                                     public void actionPerformed(ActionEvent e) {256                                         int choose = JOptionPane.showConfirmDialog(null, "确定删除!", "删除对话框", JOptionPane.YES_NO_OPTION);257                                            if(choose == JOptionPane.OK_OPTION){258                                                QQP.remove(lab.getParent());259                                                int cnt = QQP.getComponentCount();260                                                int h = QQP.getHeight() - (cnt-1)*60;261                                              if(h < 0) h=60;262                                                if(cnt >= 1)263                                                  QQP.getComponent(cnt-1).setPreferredSize(new Dimension(250, h));264                                                265                                                cnt = QQP.getComponentCount();266                                                if(cnt*60 <= QQPheight)267                                                    QQP.setPreferredSize(new Dimension(QQP.getWidth(), QQPheight));268                                                else 269                                                    QQP.setPreferredSize(new Dimension(QQP.getWidth(), cnt*60));270                                                QQP.updateUI();271                                                272                                                String NameAndIP = lab.getText();273                                               String name = NameAndIP.substring(0, NameAndIP.indexOf(‘:‘));274                                                QQset.remove(name);275                                                QQFrame fm = QQmap.get(name);276                                                if(fm != null) fm.dispose();277                                                QQmap.remove(name);278                                            }279                                     }280                               });281                                282                                JMenuItem edit = new JMenuItem("编辑");283                                edit.addActionListener(new ActionListener() {284                                 285                               public void actionPerformed(ActionEvent e) {286                                     //得到之前的数据!287                                     String content = lab.getText();288                                     //从新设置到文本框中289                                     InputDialog id = new InputDialog(content.substring(content.indexOf(‘:‘)+1), content.substring(0, content.indexOf(‘:‘)));290                                     if(id.key == InputDialog.CANCELBTN || id.key== 0) return;291                                     lab.setText(id.NAME + ":" + id.IP);292                                 }293                               });294                                edit.setFont(new Font("华文行楷", Font.ITALIC, 20));295                                edit.setForeground(new Color(255, 0, 255));296                                pm.setBorderPainted(true);297                                pm.setBackground(new Color(125, 0, 125));298                                pm.add(del);  pm.add(edit);299                                pm.show(lab, e.getX(), e.getY());300                           }301                      }302                      303              });304         }305         306         //内部类,用来访问Frame中的数据成员307         class InputDialog extends Dialog{308             private JLabel ipLabel = new JLabel("IP地址:");309             private JLabel nameLabel = new JLabel("姓名:");310             private JButton okBtn = new JButton("确定");311             private JButton cleBtn = new JButton("取消");312             private JTextField ipText = new JTextField(20);313             private JTextField nameText = new JTextField(20);314             private static final int OKBTN = 1;315             private static final int CANCELBTN = 2;316             private int key = 0;317             private String IP = null, NAME = null; 318             void initDialog(){319                 JPanel p = null;320                 setModal(true);321                 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));322                 323                 add(p = new JPanel());324                 p.setLayout(new FlowLayout(FlowLayout.CENTER));325                 ipLabel.setPreferredSize(new Dimension(50, 12));326                 p.add(ipLabel); p.add(ipText);327                 328                 329                 add(p = new JPanel());330                 p.setLayout(new FlowLayout(FlowLayout.CENTER));331                 nameLabel.setPreferredSize(new Dimension(50, 12));332                 p.add(nameLabel); p.add(nameText);333                 334                 add(p = new JPanel());335                 p.setLayout(new FlowLayout(FlowLayout.CENTER));336                 p.add(okBtn); p.add(cleBtn);337                 338                 addWindowListener(new WindowAdapter() {339                         public void windowClosing(WindowEvent e) {340                              key = 0;341                              dispose();342                         }343                 });344                 345                 addMouseListener(new MouseAdapter() {346                         public void mouseClicked(MouseEvent e) {347                              requestFocus();348                         }349                 });350                 351                 okBtn.addMouseListener(new MouseAdapter() {352                         public void mouseClicked(MouseEvent e) {353                              key = InputDialog.OKBTN;354                              if("".equals(ipText.getText()) || "".equals(nameText.getText()) || !checkIP(ipText.getText()) )355                                      JOptionPane.showMessageDialog(null, "信息不全或者IP填写错误!");356                              else{357                                  String name = nameText.getText();358                                  if(QQset.contains(name)){359                                      JOptionPane.showMessageDialog(null, "好友已存在!", "QQ好友", JOptionPane.OK_OPTION);360                                      return ;361                                  }362                                  QQset.add(name);//将新增加的好友添加到集合中!363                                  IP = ipText.getText();364                                  NAME = nameText.getText();365                                  dispose();366                              }367                         }368                 });369                 370                 cleBtn.addMouseListener(new MouseAdapter() {371                         public void mouseClicked(MouseEvent e) {372                             key = InputDialog.CANCELBTN;373                             dispose();374                         }375                 });376                 setSize(300, 200);377                 setLocation(200, 200);378                 setVisible(true);379             }380             381             public InputDialog(String ip, String name){382                 super(new Frame());383                 ipText.setText(ip);384                 nameText.setText(name);385                 initDialog();386             }387             388             public InputDialog(){389                 super(new Frame());390                 initDialog();391             }392             393             public boolean checkIP(String ip){394                 int i, begin = 0, end;395                 for(i = 1; i <= 4; ++i){396                     end = ip.indexOf(‘.‘, begin);397                     if(end == -1) return false;398                     int p = Integer.valueOf(ip.substring(begin, end));399                     if(p < 0 || p > 255)  return false;400                 }401                 return true;402             }403             404             public String getIPText(){405                 return IP;406             }407             408             public String getNameText(){409                 return NAME;410             }411             412         }413         414         415         private static ServerSocketQQ ss = null;416         private static QQReceive qr = null;417         418         public static void main(String[] args){419 420              ss = new ServerSocketQQ();421              new Thread(ss).start();422              if(ServerSocketQQ.getPort() < 1) return;423              424              qr = new QQReceive();425              new Thread(qr).start();426              if(qr.getPort() < 1)  return ;427              428             new QQDialog();429         }430 }
View Code
  1 package testFour;  2   3 import java.awt.Color;  4 import java.awt.Dimension;  5 import java.awt.FlowLayout;  6 import java.awt.Font;  7 import java.awt.Frame;  8 import java.awt.Label;  9 import java.awt.TextArea; 10 import java.awt.event.KeyAdapter; 11 import java.awt.event.KeyEvent; 12 import java.awt.event.MouseAdapter; 13 import java.awt.event.MouseEvent; 14 import java.awt.event.WindowAdapter; 15 import java.awt.event.WindowEvent; 16 import java.io.File; 17 import java.io.FileInputStream; 18 import java.io.IOException; 19 import java.io.InputStream; 20 import java.io.OutputStream; 21 import java.net.DatagramPacket; 22 import java.net.DatagramSocket; 23 import java.net.InetAddress; 24 import java.net.InetSocketAddress; 25 import java.net.Socket; 26 import java.net.SocketAddress; 27 import java.net.UnknownHostException; 28 import java.util.Calendar; 29 import java.util.Iterator; 30 import java.util.Map; 31  32 import javax.imageio.ImageIO; 33 import javax.imageio.ImageReader; 34 import javax.imageio.stream.ImageInputStream; 35 import javax.swing.BoxLayout; 36 import javax.swing.JButton; 37 import javax.swing.JFileChooser; 38 import javax.swing.JOptionPane; 39 import javax.swing.JPanel; 40 import javax.swing.JScrollPane; 41 import javax.swing.JTextPane; 42 import javax.swing.filechooser.FileFilter; 43  44  45  46 public class QQFrame extends Frame{ 47      private TextArea taSend = new TextArea(); 48      private JTextPane taReceive = new JTextPane(); 49      private JScrollPane p = new JScrollPane(taReceive); 50      private JPanel pSend = new JPanel(); 51      private JPanel pReceive = new JPanel(); 52      private Label laSend = new Label("发送端....."); 53      private Label laReceive = new Label("接收端....."); 54      private JButton FileBtn = new JButton("传输文件"); 55      private JButton PicuterBtn = new JButton("发送图片"); 56      private InetAddress sendIAD = null;//当前窗口所对应的好友所在机器的IP对象 57      private String QQname = null;//该对话框所对应的好友的姓名 58      private Socket st =null; 59      private String text; 60      private DatagramSocket ds = null; 61      62      public QQFrame(String name, byte[] ipBuf) throws RuntimeException{ 63          try { 64             sendIAD = InetAddress.getByAddress(ipBuf); 65          } catch (UnknownHostException e3) { 66             JOptionPane.showMessageDialog(null, "IP错误", "错误类型", JOptionPane.OK_CANCEL_OPTION); 67             return ; 68          } 69           70          ds = QQReceive.getUdpSocket(); 71          if(ds == null)  throw new RuntimeException("udp Socket出错!"); 72           73          QQname = name; 74          text = ""; 75          setSize(600, 600); 76          setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 77          pSend.setLayout(new FlowLayout(FlowLayout.LEFT)); 78          pSend.add(laSend); 79          pSend.add(FileBtn); 80          pSend.add(PicuterBtn); 81          pReceive.setLayout(new FlowLayout(FlowLayout.LEFT)); 82          pReceive.add(laReceive); 83           84          taReceive.setForeground(new Color(255, 0, 255)); 85          add(pReceive); 86          add(p); 87          add(pSend); 88          add(taSend); 89          setTitle("我的好友 " + QQname); 90           91           92          taSend.setPreferredSize(new Dimension(0, 200)); 93          taReceive.setPreferredSize(new Dimension(0, 400)); 94           95          taSend.setFont(new Font("仿宋", Font.PLAIN, 20)); 96          taReceive.setFont(new Font("黑体", Font.PLAIN, 25)); 97           98          taReceive.setEditable(false);//不能进行文本的编辑,但是可以进行访问 99          100          taSend.addKeyListener(new KeyAdapter() {101             102              public void keyPressed(KeyEvent e) {103                 if(e.getKeyCode() == KeyEvent.VK_ENTER){104                      text = taSend.getText();105                      if(text == null) return;106                      text += "\n\n";107                      byte[] bt = text.getBytes();108                      DatagramPacket dp = null;109                      try {110                          //向指定的ip和端口发送数据~!111                          //先说明一下数据是谁发送过来的!112                          dp = new DatagramPacket(QQname.getBytes(), QQname.getBytes().length, sendIAD, QQReceive.getPort());113                          ds.send(dp);114                          115                          dp = new DatagramPacket("PARAGRAPH".getBytes(), "PARAGRAPH".getBytes().length, sendIAD, QQReceive.getPort());116                          ds.send(dp);117                          dp = new DatagramPacket(bt, bt.length, sendIAD, QQReceive.getPort());118                          ds.send(dp);119                      } catch (IOException e1) {120                         e1.printStackTrace();121                      }122                      123                      synchronized(QQ.class){//发送端向接收窗口添加数据时 要 和 接收端向接收窗口添加数据时同步!124                          byte[] x = new String(QQname + " : ").getBytes();125                          QQ.setTextPane(taReceive, x, x.length, QQ.PARAGRAPH, QQ.SEND);126                          x = text.getBytes();127                          QQ.setTextPane(taReceive, x, x.length, QQ.PARAGRAPH, QQ.SEND*3);128                      }129                      130                      taSend.setText("");//发送端清空131                      e.consume();//不让这个回车字符在输入端显示!132                      return ;133                 }134             }135              136          });137          138          addWindowListener(new WindowAdapter() {139 140             public void windowClosing(WindowEvent e) {141                 Map<String, QQFrame>mp = QQDialog.getMap();142                 mp.remove(QQname);143                 dispose();144             }145              146          });147          148          FileBtn.addMouseListener(new MouseAdapter() {//文件传输149                 public void mouseClicked(MouseEvent e) {150                      JFileChooser jfc = new JFileChooser();151                      jfc.showOpenDialog(null);152                      File fl = jfc.getSelectedFile();153                      if(fl == null) return ;154                      try {155                         st =  new Socket();//尝试连接对方156                         st.connect(new InetSocketAddress(sendIAD, ServerSocketQQ.getPort()), 1000);157                      } catch (IOException e2) {158                         st = null;159                         JOptionPane.showMessageDialog(null, "连接错误!", "ServerSocket", JOptionPane.OK_CANCEL_OPTION);160                      }161                      if(st != null){162                         try {163                             byte[] bt = new byte[1024];164                             InputStream is = st.getInputStream(); 165                             OutputStream os = st.getOutputStream();166                             //先说明一下是谁发送过来的!167                             os.write(QQname.getBytes());168                             os.flush();169                         170                             //向对方首先发送文件名, 然后发送文件内容!171                             os.write(fl.getName().getBytes());172                             os.flush();173                             174                             int len;175                             InputStream fis = new FileInputStream(fl);176                             while( (len = fis.read(bt)) != -1){177                                 os.write(bt, 0, len);178                                 os.flush();179                             }180                             bt = new String(Calendar.getInstance().getTime().toString() + ":文件已传输!").getBytes();181                             QQ.setTextPane(taReceive, bt, bt.length, QQ.FILE, QQ.FILEX);182                             st.shutdownOutput();//输出流结束,并标记一下,使服务端知道客户端输出已经结束了!183                             st.close();184                         185                         } catch (IOException e1) {186                             e1.printStackTrace();187                         }188                      }189                 }190          });191          192          PicuterBtn.addMouseListener(new MouseAdapter() {193                 public void mouseClicked(MouseEvent e) {194                     JFileChooser jfc = new JFileChooser();195                     jfc.setFileFilter(new PicuterFilter());//设置当前的文件过滤器!196                     jfc.setAcceptAllFileFilterUsed(false);//设置所有文件过滤器不使用!197                     //jfc.addChoosableFileFilter(new Filter());198                     jfc.showOpenDialog(null);199                     200                    //将输入流按照下面方式处理, 根据Iterator<ImageReader> itImage是否能201                    //成功的返回一个ImageReader对象确认该流文件是否是一个图片文件!202                    //并ImageReader类中的getFormatName()得到文件的格式!203                    //通过最后可以通过ImageIcon的byte[]构造函数建立ImageIcon对象!204                    //最后将图片显示在面板上!205                     File fl = jfc.getSelectedFile();206                     if(fl == null) return ;207                     try{208                              InputStream is = new FileInputStream(fl);209                              ImageInputStream iis = ImageIO.createImageInputStream(is);210                              Iterator<ImageReader> itImage = ImageIO.getImageReaders(iis);211                              if(itImage.hasNext()){212                                   ImageReader reader = itImage.next();213                                   byte[] imageByte = new byte[1024*64];214                                   int len = iis.read(imageByte);215                                   if(len > 64 * 1000){216                                       JOptionPane.showMessageDialog(new Frame(), "图片过大!请采用文件传输!");217                                       return ;218                                   }219                                   DatagramPacket dp = null;220                                   //先说明一下数据是谁发送过来的!221                                   dp = new DatagramPacket(QQname.getBytes(), QQname.getBytes().length, sendIAD, QQReceive.getPort());222                                   ds.send(dp);223                                   224                                   dp = new DatagramPacket("PICUTER".getBytes(), "PICUTER".getBytes().length, InetAddress.getLocalHost(), QQReceive.getPort());225                                   ds.send(dp);226                                   dp = new DatagramPacket(imageByte, len, InetAddress.getLocalHost(), QQReceive.getPort());227                                   ds.send(dp);228                                   synchronized(QQ.class){229                                       byte[] name = new String(dp.getAddress().getHostName() + " : ").getBytes();230                                       QQ.setTextPane(taReceive, name, name.length, QQ.PARAGRAPH, QQ.SEND);231                                       QQ.setTextPane(taReceive, imageByte, len, QQ.PICUTER, 0);232                                   }233                              }234                              else throw new NoPicuterException("不是一张图片!");235                     }catch(IOException ex){236                         ex.printStackTrace();237                     }238                 }239          });240          241          setVisible(true);242      }243      244      public DatagramSocket getDs(){245          return ds;246      }247      248      public JTextPane getReceive(){249          return taReceive;250      }251      252 }253 254 class PicuterFilter extends FileFilter {255      256     public boolean accept(File file){257            return(file.isDirectory() || file.getName().endsWith(".gif") 258                   || file.getName().endsWith(".png") || file.getName().endsWith(".bmp")259                   || file.getName().endsWith(".jpg") );260            /* 返回要显示的文件类型 */261            /*262             *   File.isDirectory()测试此抽象路径名表示的文件是否是一个目录263            */264       }265       266       public String getDescription() {267           return("Picuter Files(*.gif, *.png, *.jpg, *.bmp)");                  //返回显示文件类型的描述268       }269 }270 271 class NoPicuterException extends IOException{272     public NoPicuterException(String x){273         super(x);274     }275 }
View Code
 1 package testFour; 2  3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.SocketException; 7 import java.util.Map; 8 import java.util.Set; 9 10 import javax.swing.JOptionPane;11 12 public class QQReceive implements Runnable{13     private QQFrame fm = null;14     private static DatagramSocket ds = null;15     private static int port = 10101;16     private boolean flag = true;17     18     public void setFlag(){19         if(ds != null)20             ds.close();21         flag = false;22     }23     public QQReceive(){24         try {25             //建立udp通信方式26             ds = new DatagramSocket(port);27          } catch (SocketException e1) {28              port = -1;29              JOptionPane.showMessageDialog(null, "DatagramSocket端口绑定错误!", "绑定错误", JOptionPane.OK_CANCEL_OPTION);30         }31     }32     33     public static DatagramSocket getUdpSocket(){34         return ds;35     } 36     37     public static int getPort(){38         return port;39     }40     41     public DatagramSocket getDS(){42         return ds;43     }44     45     public void run(){46         if(ds == null) return ;47         while(flag){48             byte[] bt = new byte[10024*10]; 49             int flag = 0;50             DatagramPacket dp = new DatagramPacket(bt, bt.length); 51             try {52                     ds.receive(dp);53                     54                     String name = new String(dp.getData(), 0, dp.getLength());55                     Map<String, QQFrame>mp = QQDialog.getMap();56                     Set<String>  set = QQDialog.getSet();57                     fm = mp.get(name);58                     if(set.contains(name) && fm == null){//如果存在该好友,但是不存在对应的对话窗口59                          //自动产生对话窗口60                          Map<String, byte[]> nameToIP = QQDialog.getNameToIP();61                          fm = new QQFrame(name, nameToIP.get(name));62                     }63                     ds.receive(dp);64                     String tag = new String(dp.getData(), 0, dp.getLength());65                     if( tag.equals("FILE") )66                         flag = QQ.FILE;67                     else if( tag.equals("PICUTER"))68                         flag = QQ.PICUTER;69                     else if( tag.equals("PARAGRAPH"))70                         flag = QQ.PARAGRAPH;71                     72                     ds.receive(dp);73                 74             } catch (IOException e) {75                 e.printStackTrace();76             }77             synchronized(QQ.class){78                 if(fm == null) continue;79                 byte[] x = new String(dp.getAddress().getHostName() + " : ").getBytes();80                 QQ.setTextPane(fm.getReceive(), x, x.length, QQ.PARAGRAPH, QQ.RECEIVE);81                 QQ.setTextPane(fm.getReceive(), dp.getData(), dp.getLength(), flag, QQ.RECEIVE*3);82             }83         }84     }85 }
View Code
  1 package testFour;  2   3 import java.io.File;  4 import java.io.FileOutputStream;  5 import java.io.IOException;  6 import java.io.InputStream;  7 import java.io.OutputStream;  8 import java.net.ServerSocket;  9 import java.net.Socket; 10 import java.util.Calendar; 11 import java.util.Map; 12 import java.util.Set; 13  14 import javax.swing.JOptionPane; 15  16 public class ServerSocketQQ implements Runnable{ 17     private ServerSocket sst = null; 18     private Socket st = null; 19     private static int port = 10100; 20     private boolean flag = true; 21      22     public void setFlag(){ 23         if(sst != null) 24             try { 25                 sst.close(); 26             } catch (IOException e) { 27                 e.printStackTrace(); 28             } 29         flag = false; 30     } 31      32     public static int getPort(){ 33         return port; 34     } 35      36     public ServerSocketQQ(){ 37         //建立服务端 38         try { 39             sst = new ServerSocket(port); 40         } catch (IOException e) { 41             port = -1; 42             JOptionPane.showMessageDialog(null, "ServerSocket端口绑定错误!", "绑定错误", JOptionPane.OK_CANCEL_OPTION); 43         } 44          45     } 46      47     public void run(){ 48         byte[] bt = null; 49         int len = 0; 50         if(sst == null)  return ; 51         while(true){ 52             try{ 53                 //侦听并接受到此服务套接字的连接。此方法在进行连接之前一直阻塞。 创建新套接字  54                 st = sst.accept(); 55                 //得到客户端传输过来的流 56                 InputStream is = st.getInputStream(); 57                 OutputStream os  = st.getOutputStream(); 58                 bt = new byte[1024]; 59                  60                 len = is.read(bt); 61                 String name = new String(bt, 0, len); 62                 QQFrame fm = null; 63                 Map<String, QQFrame>mp = QQDialog.getMap(); 64                 Set<String>  set = QQDialog.getSet(); 65                 fm = mp.get(name); 66                 if(set.contains(name) && fm == null){//如果存在该好友,但是不存在对应的对话窗口 67                      //自动产生对话窗口 68                      Map<String, byte[]> nameToIP = QQDialog.getNameToIP(); 69                      fm = new QQFrame(name, nameToIP.get(name)); 70                 } 71                 if(fm == null){//对方不存在该好友! 72                     st.close(); 73                     continue; 74                 } 75                  76                 len = is.read(bt); 77                 String fileName = new String(bt, 0, len); 78                  79                 int choose = JOptionPane.showConfirmDialog(null, "接受或不接受", "文件传输提示", JOptionPane.YES_NO_OPTION); 80                 if(choose == JOptionPane.NO_OPTION){ 81                     bt = new String(Calendar.getInstance().getTime().toString() + ":文件接受失败!").getBytes(); 82                     QQ.setTextPane(fm.getReceive(), bt, bt.length, QQ.FILE, QQ.FILEX); 83                     st.close(); 84                     continue; 85                 } 86                 FileOutputStream fos = new FileOutputStream( new File(fileName) ); 87                 while( (len = is.read(bt)) != -1 ){//先将流文件变成byte[], 然后利用套接字的输出流发送给客户端 88                      fos.write(bt); 89                      fos.flush(); 90                 } 91                 bt = new String(Calendar.getInstance().getTime().toString() + ":文件接受成功!").getBytes(); 92                 QQ.setTextPane(fm.getReceive(), bt, bt.length, QQ.FILE, QQ.FILEX); 93                 st.close(); 94            }catch(IOException e){ 95                e.printStackTrace(); 96            } 97         } 98      } 99     100 }
View Code

 

java模拟一个简单的QQ