这几天偶然想研究下P2P通信的原理,于是就用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<String,SocketAddress> 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<String, SocketAddress> 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<String, SocketAddress> 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<String, SocketAddress> entry : userMap.entrySet()) { DatagramPacket data=new DatagramPacket(msg.getBytes(),msg.getBytes().length,entry.getValue()); client.send(data); } this.msgText.setText(""); } } catch(Exception ee){} } } }
服务器端:
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<Map> userList=new ArrayList<Map>(); //在线用户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(); } }
相关推荐
基于java的p2p聊天程序,具有传送文件功能。局域网聊天室发现,对等点连接建立单独对话。(所有程序只是作为练习,具有不完善地方,仅供参考。)
实现基于P2P的聊天程序,用java语言编写,有界面可以选择不同的用户以及群聊,可以设置字体。
基于java socket的p2p聊天程序,可以实现点对点聊天,北京邮电大学软件工程实习小学期作业!
java实现P2P聊天程序,使用UDP协议。 含有GUI,带有注释。 若有不足,欢迎指正。
比较简单的程序,适合刚开始接触用socket编程。可以发送不同字体的聊天信息。根据Ip选择不同聊天用户。
Java实现的聊天程序。支持客户端与客户端的通信。适合初学者学习研究。。。。。。
一个简单的P2P即时聊天系统,实现功能如下: 1) 点对点的单人聊天 2) 多人同时聊天 3) 用户可以自由加入和退出。
这是用java做的基于网络编程的聊天软件,包括客户端也服务器两个部分,很适合初学者学习网络编程。
很简单的p2p聊天程序 使用socket编写 没有使用图形界面 只有点对点 聊天功能
暂时仅仅设计了以下几个功能点: 1.点对点单人聊天; 2.多人在线同时聊天; 3.用户可以自由加入和退出系统; 4.具备用户在线状态监听;
利用RSA算法的公私密钥对DES算法的密钥进行加解密,对称DES密钥用来对聊天消息进行加解密,SHA算法用来对传输的数据进行数据校验。Java本版的机遇socket的聊天程序,课程学习资料和作业。附带详细代码说明文档。
Java P2P聊天服务端源码,通过NAT打洞技术,借助P2P服务端,采用客户端程序可以实现客户端点对点通讯
#自述##概述这是一个简单的P2P聊天项目。 主要是为了演示简单的P2P概念,但不包括分布式网络概念(你应该通过谷歌和维基百科改进自己)。 ##例子这是一个eclipse项目,你可以将它导入到eclipse中,然后导航到...
用JAVA写的支持IPV6的P2P多线程聊天程序
课程设计报告,已通过检查,即下即用,简单易懂。
应用可视化编程工具,设计开发P2P聊天程序,实现局域网内点对点的信息对话。基本功能要求:可实现文本信息、表情信息等的对话,同时具有自动答复功能。
《分布式系统》课程的一个作业,作为一个小Demo给大家参考一下。其实聊天窗口有点小bug,就交给你们去处理吧^_^
用JAVA的socket编程,做的一个简单即时通讯程序。。很简单