Chinaunix首页 | 论坛 | 博客
  • 博客访问: 836601
  • 博文数量: 190
  • 博客积分: 2991
  • 博客等级: 少校
  • 技术积分: 2400
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-24 18:11
文章分类

全部博文(190)

文章存档

2015年(3)

2014年(1)

2013年(65)

2012年(121)

我的朋友

分类: Java

2013-04-15 17:24:07

这几天偶然想研究下P2P通信的原理,于是就用Java写了一个,测试可以通过,但是在不同的运营商之间却有点问题,比如联通跟电信之间可能出现不通现象,不知是不是被卡杀了。

客户端:

Java代码

 

  1. import java.awt.BorderLayout;  
  2. import java.awt.event.ActionEvent;  
  3. import java.awt.event.ActionListener;  
  4. import java.awt.event.WindowAdapter;  
  5. import java.awt.event.WindowEvent;  
  6. import java.io.BufferedReader;  
  7. import java.io.FileInputStream;  
  8. import java.io.InputStreamReader;  
  9. import java.net.DatagramPacket;  
  10. import java.net.DatagramSocket;  
  11. import java.net.InetSocketAddress;  
  12. import java.net.SocketAddress;  
  13. import java.util.ArrayList;  
  14. import java.util.HashMap;  
  15. import java.util.List;  
  16. import java.util.Map;  
  17. import java.util.Map.Entry;  
  18. import java.util.Set;  
  19.   
  20. import javax.swing.JButton;  
  21. import javax.swing.JFrame;  
  22. import javax.swing.JLabel;  
  23. import javax.swing.JPanel;  
  24. import javax.swing.JScrollBar;  
  25. import javax.swing.JTextArea;  
  26. import javax.swing.JTextField;  
  27.   
  28. public class Client extends Thread implements ActionListener{  
  29.     //是否停止  
  30.     public static int STOP=0;  
  31.       
  32.     //在线用户列表  
  33.     public static Map userMap=new HashMap();  
  34.       
  35.     private DatagramSocket client;  
  36.       
  37.     private JFrame frame;  
  38.     //聊天信息  
  39.     private JTextArea info;  
  40.     //在线用户  
  41.     private JTextArea onlineUser;  
  42.     private JTextField msgText;  
  43.       
  44.     private JButton sendButton;  
  45.       
  46.     public Client(DatagramSocket client)throws Exception  
  47.     {  
  48.   
  49.         this.client=client;  
  50.         this.frame=new JFrame("P2P聊天");  
  51.         frame.setSize(800, 400);  
  52.           
  53.         sendButton=new JButton("发送");  
  54.         JScrollBar scroll=new JScrollBar();  
  55.         this.info=new JTextArea(10,30);  
  56.         //激活自动换行功能   
  57.         info.setLineWrap(true);  
  58.         info.setWrapStyleWord(true);  
  59.         info.setEditable(false);  
  60.         scroll.add(info);  
  61.           
  62.         onlineUser=new JTextArea(10,30);  
  63.         onlineUser.setLineWrap(true);  
  64.         onlineUser.setWrapStyleWord(true);  
  65.         onlineUser.setEditable(false);  
  66.           
  67.           
  68.         JPanel infopanel=new JPanel();  
  69.         infopanel.add(info,BorderLayout.WEST);  
  70.         JPanel infopanel1=new JPanel();  
  71.         JLabel label=new JLabel("在线用户");  
  72.         infopanel1.add(label, BorderLayout.NORTH);  
  73.         infopanel1.add(onlineUser, BorderLayout.SOUTH);  
  74.         infopanel.add(infopanel1,BorderLayout.EAST);  
  75.   
  76.         JPanel panel=new JPanel();  
  77.           
  78.         msgText=new JTextField(30);  
  79.       
  80.         panel.add(msgText);  
  81.         panel.add(sendButton);  
  82.         frame.add(infopanel,BorderLayout.NORTH);  
  83.         frame.add(panel,BorderLayout.SOUTH);  
  84.         frame.setVisible(true);  
  85.           
  86.         sendButton.addActionListener(this);  
  87.           
  88.         frame.addWindowListener(new   WindowAdapter(){   
  89.             public   void   windowClosing(WindowEvent   e){   
  90.                 System.exit(0);  
  91.             }   
  92.          });   
  93.           
  94.   
  95.     }  
  96.       
  97.     /** 
  98.      * 给其他在线用户发送心跳 保持session有效 
  99.      */  
  100.     private void sendSkip()  
  101.     {  
  102.         new Thread(){  
  103.             public void run()  
  104.             {  
  105.                 try  
  106.                 {  
  107.                     String msg="skip";  
  108.                     while(true)  
  109.                     {  
  110.                         if(STOP==1)  
  111.                             break;  
  112.                         if(userMap.size()>0)  
  113.                         {  
  114.                              for (Entry entry : userMap.entrySet()) {  
  115.                                  DatagramPacket data=new DatagramPacket(msg.getBytes(),msg.getBytes().length,entry.getValue());  
  116.                                 client.send(data);  
  117.                             }  
  118.                         }  
  119.                         //每10s发送一次心跳  
  120.                         Thread.sleep(10*1000);  
  121.                     }  
  122.                 }catch(Exception e){}  
  123.                   
  124.             }  
  125.         }.start();  
  126.     }  
  127.       
  128.     //主要任务是接收数据  
  129.     //可以是其他用户发来的信息,也可以是服务器发来的在线用户数据  
  130.     public void run()  
  131.     {  
  132.         try  
  133.         {  
  134.               
  135.             String msg;  
  136.             DatagramPacket data;  
  137.               
  138.             //执行心跳  
  139.             sendSkip();  
  140.               
  141.             while(true)  
  142.             {  
  143.                 if(STOP==1)  
  144.                     break;  
  145.                 byte[] buf=new byte[1024];  
  146.                 DatagramPacket packet = new DatagramPacket(buf, buf.length);  
  147.                 client.receive(packet);  
  148.                 msg=new String(packet.getData(),0,packet.getLength());  
  149.                 if(msg.length()>0)  
  150.                 {  
  151.                     if(msg.indexOf("server:")>-1)  
  152.                     {  
  153.                         //服务器数据 格式server:ID#IP:PORT,。。  
  154.                         String userdata=msg.substring(msg.indexOf(":")+1,msg.length());  
  155.                         String[] user=userdata.split(",");  
  156.                         for(String u:user)  
  157.                         {  
  158.                             if(u!=null&&u.length()>0)  
  159.                             {  
  160.                                 String[] udata=u.split("#");  
  161.                                 String ip=udata[1].split(":")[0];  
  162.                                 int port=Integer.parseInt(udata[1].split(":")[1]);  
  163.                                   
  164.                                 ip=ip.substring(1,ip.length());  
  165.                                   
  166.                                 SocketAddress adds=new InetSocketAddress(ip,port);  
  167.                                 userMap.put(udata[0], adds);  
  168.                                 //给对方打洞 发送空白报文  
  169.                                 data=new DatagramPacket(new byte[0],0,adds);  
  170.                                 client.send(data);  
  171.                                   
  172.                             }  
  173.                               
  174.                         }  
  175.                         //更新在线用户列表  
  176.                         this.onlineUser.setText("");  
  177.                         for (Map.Entry entry : userMap.entrySet()) {  
  178.                             this.onlineUser.append("用户"+entry.getKey()+"("+entry.getValue()+")\n");  
  179.                         }  
  180.   
  181.                     }  
  182.                     else if(msg.indexOf("skip")>-1);  
  183.                     else  
  184.                     {  
  185.                         //普通消息  
  186.                         this.info.append(packet.getAddress().toString()+packet.getPort()+" 说:"+msg);  
  187.                         this.info.append("\n");  
  188.                     }  
  189.                 }  
  190.             }  
  191.         }  
  192.         catch(Exception e){}  
  193.     }  
  194.       
  195.     public static void main(String args[])throws Exception  
  196.     {  
  197.           
  198.         String serverIP="122.225.99.40";///122.225.99.40  
  199.         int port=6636;  
  200.           
  201.         //构造一个目标地址  
  202.         SocketAddress target = new InetSocketAddress(serverIP, port);   
  203.           
  204.         DatagramSocket client = new DatagramSocket();  
  205.         String msg="向服务器报告!";  
  206.         byte[] buf=msg.getBytes();  
  207.         //向服务器发送上线数据  
  208.         DatagramPacket packet=new DatagramPacket(buf,buf.length,target);  
  209.         client.send(packet);  
  210.         new Client(client).start();  
  211.           
  212.     }  
  213.   
  214.       
  215.     //按钮事件  
  216.     @Override  
  217.     public void actionPerformed(ActionEvent e) {  
  218.         if(e.getSource()==this.sendButton)  
  219.         {  
  220.             try{  
  221.                 String msg=this.msgText.getText();  
  222.                 if(msg.length()>0)  
  223.                 {  
  224.                     this.info.append("我说:"+msg);  
  225.                     this.info.append("\n");  
  226.                     for (Map.Entry entry : userMap.entrySet()) {  
  227.                         DatagramPacket data=new DatagramPacket(msg.getBytes(),msg.getBytes().length,entry.getValue());  
  228.                         client.send(data);  
  229.                     }  
  230.                       
  231.                     this.msgText.setText("");  
  232.                 }  
  233.             }  
  234.             catch(Exception ee){}  
  235.         }  
  236.           
  237.     }  
  238. }  

 服务器端:

Java代码  
  1. import java.io.BufferedReader;  
  2. import java.io.BufferedWriter;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.io.OutputStreamWriter;  
  6. import java.io.PrintWriter;  
  7. import java.net.DatagramPacket;  
  8. import java.net.DatagramSocket;  
  9. import java.net.InetAddress;  
  10. import java.net.ServerSocket;  
  11. import java.net.Socket;  
  12. import java.util.ArrayList;  
  13. import java.util.HashMap;  
  14. import java.util.List;  
  15. import java.util.Map;  
  16.   
  17. /** 
  18.  * 服务端 
  19.  * @author ggxin 
  20.  * 
  21.  */  
  22. public class Server extends Thread{  
  23.     //存储所有的用户IP与端口  
  24.     public static List userList=new ArrayList();  
  25.     //在线用户IP  
  26.     public static Map users=new HashMap();  
  27.       
  28.     public static int index=1;  
  29.       
  30.     private DatagramSocket server;  
  31.       
  32.     public Server(DatagramSocket server)  
  33.     {  
  34.         this.server=server;  
  35.     }  
  36.     //线程负责给在线用户发送当前所有在线用户的信息  
  37.     public void run()  
  38.     {  
  39.         try  
  40.         {  
  41.             DatagramPacket sendPacket;  
  42.             StringBuffer msg;  
  43.             while(true)  
  44.             {  
  45.                 for(Map user:Server.userList)  
  46.                 {  
  47.                     //服务器数据,标记server:  
  48.                     msg=new StringBuffer("server:");  
  49.                     for(Map map:Server.userList)  
  50.                     {  
  51.                         if(!map.get("id").toString().equals(user.get("id").toString()))  
  52.                         {  
  53.                             msg.append(map.get("id")+"#"+map.get("ip")+":"+map.get("port"));  
  54.                             msg.append(",");  
  55.                         }  
  56.                     }  
  57.                     if(!msg.toString().equals("server:"))  
  58.                     {  
  59.                         byte[] data=msg.toString().getBytes();  
  60.                         //构造发送报文  
  61.                         sendPacket = new DatagramPacket(data, data.length, (InetAddress)user.get("ip"), (Integer)user.get("port"));    
  62.                         server.send(sendPacket);  
  63.                     }  
  64.                 }  
  65.                 Thread.sleep(2000);  
  66.                   
  67.             }  
  68.         }catch(Exception e){}  
  69.     }  
  70.       
  71.       
  72.     public static void main(String args[])throws Exception  
  73.     {  
  74.   
  75.         int port=6636;  
  76.           
  77.         //创建一个UDPsocket  
  78.         DatagramSocket server = new DatagramSocket(port);  
  79.         byte[] buf = new byte[1024];    
  80.         //接收数据的udp包  
  81.         DatagramPacket packet = new DatagramPacket(buf, buf.length);  
  82.          
  83.         //开启服务  
  84.         new Server(server).start();  
  85.   
  86.         String msg;  
  87.         //循环接收数据  
  88.         while(true)  
  89.         {  
  90.               
  91.             server.receive(packet);  
  92.               
  93.             msg=new String(packet.getData(),0,packet.getLength());  
  94.               
  95.             if(msg!=null&&msg.equals("bye"))  
  96.                 break;  
  97.               
  98.             if(msg.length()>0)  
  99.             {  
  100.                 System.out.println("收到数据来自:("+packet.getAddress()+":"+packet.getPort()+")="+msg);  
  101.                 if(!users.containsKey(packet.getAddress()+":"+packet.getPort()))  
  102.                 {  
  103.                     Map map=new HashMap();  
  104.                     map.put("id", index);  
  105.                     map.put("ip", packet.getAddress());  
  106.                     map.put("port", packet.getPort());  
  107.                     userList.add(map);  
  108.                       
  109.                     users.put(packet.getAddress()+":"+packet.getPort(), index);  
  110.                     index++;  
  111.                 }  
  112.                   
  113.             }  
  114.         }  
  115.         server.close();  
  116.     }  
  117.   
  118. }  
阅读(1382) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~