这几天偶然想研究下P2P通信的原理,于是就用Java写了一个,测试可以通过,但是在不同的运营商之间却有点问题,比如联通跟电信之间可能出现不通现象,不知是不是被卡杀了。
客户端:
Java代码
-
import java.awt.BorderLayout;
-
import java.awt.event.ActionEvent;
-
import java.awt.event.ActionListener;
-
import java.awt.event.WindowAdapter;
-
import java.awt.event.WindowEvent;
-
import java.io.BufferedReader;
-
import java.io.FileInputStream;
-
import java.io.InputStreamReader;
-
import java.net.DatagramPacket;
-
import java.net.DatagramSocket;
-
import java.net.InetSocketAddress;
-
import java.net.SocketAddress;
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import java.util.List;
-
import java.util.Map;
-
import java.util.Map.Entry;
-
import java.util.Set;
-
-
import javax.swing.JButton;
-
import javax.swing.JFrame;
-
import javax.swing.JLabel;
-
import javax.swing.JPanel;
-
import javax.swing.JScrollBar;
-
import javax.swing.JTextArea;
-
import javax.swing.JTextField;
-
-
public class Client extends Thread implements ActionListener{
-
//是否停止
-
public static int STOP=0;
-
-
//在线用户列表
-
public static Map userMap=new HashMap();
-
-
private DatagramSocket client;
-
-
private JFrame frame;
-
//聊天信息
-
private JTextArea info;
-
//在线用户
-
private JTextArea onlineUser;
-
private JTextField msgText;
-
-
private JButton sendButton;
-
-
public Client(DatagramSocket client)throws Exception
-
{
-
-
this.client=client;
-
this.frame=new JFrame("P2P聊天");
-
frame.setSize(800, 400);
-
-
sendButton=new JButton("发送");
-
JScrollBar scroll=new JScrollBar();
-
this.info=new JTextArea(10,30);
-
//激活自动换行功能
-
info.setLineWrap(true);
-
info.setWrapStyleWord(true);
-
info.setEditable(false);
-
scroll.add(info);
-
-
onlineUser=new JTextArea(10,30);
-
onlineUser.setLineWrap(true);
-
onlineUser.setWrapStyleWord(true);
-
onlineUser.setEditable(false);
-
-
-
JPanel infopanel=new JPanel();
-
infopanel.add(info,BorderLayout.WEST);
-
JPanel infopanel1=new JPanel();
-
JLabel label=new JLabel("在线用户");
-
infopanel1.add(label, BorderLayout.NORTH);
-
infopanel1.add(onlineUser, BorderLayout.SOUTH);
-
infopanel.add(infopanel1,BorderLayout.EAST);
-
-
JPanel panel=new JPanel();
-
-
msgText=new JTextField(30);
-
-
panel.add(msgText);
-
panel.add(sendButton);
-
frame.add(infopanel,BorderLayout.NORTH);
-
frame.add(panel,BorderLayout.SOUTH);
-
frame.setVisible(true);
-
-
sendButton.addActionListener(this);
-
-
frame.addWindowListener(new WindowAdapter(){
-
public void windowClosing(WindowEvent e){
-
System.exit(0);
-
}
-
});
-
-
-
}
-
-
/**
-
* 给其他在线用户发送心跳 保持session有效
-
*/
-
private void sendSkip()
-
{
-
new Thread(){
-
public void run()
-
{
-
try
-
{
-
String msg="skip";
-
while(true)
-
{
-
if(STOP==1)
-
break;
-
if(userMap.size()>0)
-
{
-
for (Entry entry : userMap.entrySet()) {
-
DatagramPacket data=new DatagramPacket(msg.getBytes(),msg.getBytes().length,entry.getValue());
-
client.send(data);
-
}
-
}
-
//每10s发送一次心跳
-
Thread.sleep(10*1000);
-
}
-
}catch(Exception e){}
-
-
}
-
}.start();
-
}
-
-
//主要任务是接收数据
-
//可以是其他用户发来的信息,也可以是服务器发来的在线用户数据
-
public void run()
-
{
-
try
-
{
-
-
String msg;
-
DatagramPacket data;
-
-
//执行心跳
-
sendSkip();
-
-
while(true)
-
{
-
if(STOP==1)
-
break;
-
byte[] buf=new byte[1024];
-
DatagramPacket packet = new DatagramPacket(buf, buf.length);
-
client.receive(packet);
-
msg=new String(packet.getData(),0,packet.getLength());
-
if(msg.length()>0)
-
{
-
if(msg.indexOf("server:")>-1)
-
{
-
//服务器数据 格式server:ID#IP:PORT,。。
-
String userdata=msg.substring(msg.indexOf(":")+1,msg.length());
-
String[] user=userdata.split(",");
-
for(String u:user)
-
{
-
if(u!=null&&u.length()>0)
-
{
-
String[] udata=u.split("#");
-
String ip=udata[1].split(":")[0];
-
int port=Integer.parseInt(udata[1].split(":")[1]);
-
-
ip=ip.substring(1,ip.length());
-
-
SocketAddress adds=new InetSocketAddress(ip,port);
-
userMap.put(udata[0], adds);
-
//给对方打洞 发送空白报文
-
data=new DatagramPacket(new byte[0],0,adds);
-
client.send(data);
-
-
}
-
-
}
-
//更新在线用户列表
-
this.onlineUser.setText("");
-
for (Map.Entry entry : userMap.entrySet()) {
-
this.onlineUser.append("用户"+entry.getKey()+"("+entry.getValue()+")\n");
-
}
-
-
}
-
else if(msg.indexOf("skip")>-1);
-
else
-
{
-
//普通消息
-
this.info.append(packet.getAddress().toString()+packet.getPort()+" 说:"+msg);
-
this.info.append("\n");
-
}
-
}
-
}
-
}
-
catch(Exception e){}
-
}
-
-
public static void main(String args[])throws Exception
-
{
-
-
String serverIP="122.225.99.40";///122.225.99.40
-
int port=6636;
-
-
//构造一个目标地址
-
SocketAddress target = new InetSocketAddress(serverIP, port);
-
-
DatagramSocket client = new DatagramSocket();
-
String msg="向服务器报告!";
-
byte[] buf=msg.getBytes();
-
//向服务器发送上线数据
-
DatagramPacket packet=new DatagramPacket(buf,buf.length,target);
-
client.send(packet);
-
new Client(client).start();
-
-
}
-
-
-
//按钮事件
-
@Override
-
public void actionPerformed(ActionEvent e) {
-
if(e.getSource()==this.sendButton)
-
{
-
try{
-
String msg=this.msgText.getText();
-
if(msg.length()>0)
-
{
-
this.info.append("我说:"+msg);
-
this.info.append("\n");
-
for (Map.Entry entry : userMap.entrySet()) {
-
DatagramPacket data=new DatagramPacket(msg.getBytes(),msg.getBytes().length,entry.getValue());
-
client.send(data);
-
}
-
-
this.msgText.setText("");
-
}
-
}
-
catch(Exception ee){}
-
}
-
-
}
-
}
服务器端:
Java代码
-
import java.io.BufferedReader;
-
import java.io.BufferedWriter;
-
import java.io.IOException;
-
import java.io.InputStreamReader;
-
import java.io.OutputStreamWriter;
-
import java.io.PrintWriter;
-
import java.net.DatagramPacket;
-
import java.net.DatagramSocket;
-
import java.net.InetAddress;
-
import java.net.ServerSocket;
-
import java.net.Socket;
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import java.util.List;
-
import java.util.Map;
-
-
/**
-
* 服务端
-
* @author ggxin
-
*
-
*/
-
public class Server extends Thread{
-
//存储所有的用户IP与端口
-
public static List
-
//在线用户IP
-
public static Map users=new HashMap();
-
-
public static int index=1;
-
-
private DatagramSocket server;
-
-
public Server(DatagramSocket server)
-
{
-
this.server=server;
-
}
-
//线程负责给在线用户发送当前所有在线用户的信息
-
public void run()
-
{
-
try
-
{
-
DatagramPacket sendPacket;
-
StringBuffer msg;
-
while(true)
-
{
-
for(Map user:Server.userList)
-
{
-
//服务器数据,标记server:
-
msg=new StringBuffer("server:");
-
for(Map map:Server.userList)
-
{
-
if(!map.get("id").toString().equals(user.get("id").toString()))
-
{
-
msg.append(map.get("id")+"#"+map.get("ip")+":"+map.get("port"));
-
msg.append(",");
-
}
-
}
-
if(!msg.toString().equals("server:"))
-
{
-
byte[] data=msg.toString().getBytes();
-
//构造发送报文
-
sendPacket = new DatagramPacket(data, data.length, (InetAddress)user.get("ip"), (Integer)user.get("port"));
-
server.send(sendPacket);
-
}
-
}
-
Thread.sleep(2000);
-
-
}
-
}catch(Exception e){}
-
}
-
-
-
public static void main(String args[])throws Exception
-
{
-
-
int port=6636;
-
-
//创建一个UDPsocket
-
DatagramSocket server = new DatagramSocket(port);
-
byte[] buf = new byte[1024];
-
//接收数据的udp包
-
DatagramPacket packet = new DatagramPacket(buf, buf.length);
-
-
//开启服务
-
new Server(server).start();
-
-
String msg;
-
//循环接收数据
-
while(true)
-
{
-
-
server.receive(packet);
-
-
msg=new String(packet.getData(),0,packet.getLength());
-
-
if(msg!=null&&msg.equals("bye"))
-
break;
-
-
if(msg.length()>0)
-
{
-
System.out.println("收到数据来自:("+packet.getAddress()+":"+packet.getPort()+")="+msg);
-
if(!users.containsKey(packet.getAddress()+":"+packet.getPort()))
-
{
-
Map map=new HashMap();
-
map.put("id", index);
-
map.put("ip", packet.getAddress());
-
map.put("port", packet.getPort());
-
userList.add(map);
-
-
users.put(packet.getAddress()+":"+packet.getPort(), index);
-
index++;
-
}
-
-
}
-
}
-
server.close();
-
}
-
-
}
阅读(1411) | 评论(0) | 转发(0) |