这几天偶然想研究下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聊天程序详解】 Java是一种广泛使用的编程语言,尤其在开发网络应用程序时,其强大的类库和跨平台特性使其成为首选。基于Java的P2P(peer-to-peer)聊天程序是一种允许用户直接相互通信,而无需通过中心...
【P2P聊天程序(JAVA)】是一种网络通信应用程序,它使用对等网络(P2P,Peer-to-Peer)架构来实现用户之间的实时交流。P2P技术允许网络中的每个节点既是客户端也是服务器,因此在聊天程序中,每个用户都可以发送和...
【JAVA P2P聊天程序】是一个基于Java编程语言实现的简单聊天应用,它利用了TCP协议进行通信,展示了如何在对等网络模式下进行数据交换。这个程序特别适合初学者,帮助他们理解如何使用Socket编程来创建网络连接,...
在这个“基于java socket的P2P聊天程序”项目中,我们主要会涉及到以下关键知识点: 1. **Socket概念**:Socket是网络上的进程间通信(IPC)的一种方式,它允许两台机器相互通信。在Java中,`java.net.Socket`类和`...
在"java聊天程序"这个压缩包中,你应该能找到实现上述功能的源代码文件,通过阅读和运行这些代码,你可以深入理解Java P2P聊天程序的设计与实现。对于初学者来说,这是一个很好的实践项目,有助于巩固Java基础知识,...
Java实现的P2P即时聊天程序是一个基于网络通信技术的软件应用,主要用于提供实时的、点对点的以及多人互动的聊天功能。在本项目中,我们主要关注以下几个核心知识点: 1. **Java网络编程**:Java提供了丰富的API...
java实现P2P聊天程序,使用UDP协议。 含有GUI,带有注释。 若有不足,欢迎指正。
Java P2P聊天软件是一种基于Socket编程实现的对等网络通信应用。在本文中,我们将深入探讨Java语言、P2P技术以及Socket编程在构建聊天软件中的应用。 首先,Java是一种广泛使用的面向对象的编程语言,它具有跨平台...
【标题】"用Java做的P2P聊天软件"揭示了这个项目的核心技术栈,即Java编程语言,以及它实现的是一个点对点(P2P)的通信模式。点对点网络是一种分布式网络架构,其中每个节点(在这里是聊天客户端)都可以作为服务...
【Java P2P聊天程序详解】 本项目是一个基于Java实现的P2P(Peer-to-Peer)聊天程序,主要用于教学目的,展示了在分布式系统中如何构建一个简单的通信平台。在这个程序中,我们将深入探讨以下几个核心知识点: 1. ...
在Java中实现P2P聊天程序,主要涉及以下几个关键点: 1. **Socket编程**:Socket是网络通信的基本组件,它提供了应用程序间的通信端点。在Java中,`java.net.Socket` 和 `java.net.ServerSocket` 类用于创建客户端...
总的来说,这个项目是一个实践性的学习案例,通过实现一个简单的P2P聊天应用,展示了Java Swing在UI设计上的能力,多线程在并发处理中的重要性,以及Socket和UDP在实时网络通信中的应用。对于想要深入理解Java网络...
在本文中,我们将深入探讨如何...通过分析这些代码,我们可以进一步理解P2P聊天系统的具体实现细节。在实际开发中,可以在此基础上扩展功能,例如添加文件传输、语音聊天、用户认证等,以构建更完善的P2P即时通讯平台。
### Java实现P2P通信的关键知识点 #### 一、P2P通信模型及关键技术分析 ##### (一)信息的传递 **1. P2P通信模型** P2P(Peer-to-Peer)通信模型是一种分布式网络架构,其中的每一个节点既是服务的提供者也是...
本项目利用Java的Socket编程技术,实现了一个简单的类QQ即时通讯程序,旨在提供基本的聊天功能。下面我们将深入探讨相关知识点。 首先,Java Socket编程是Java网络编程的基础,它提供了在网络之间两台计算机进行...
利用RSA算法的公私密钥对DES算法的密钥进行加解密,对称DES密钥用来对聊天消息进行加解密,SHA算法用来对传输的数据进行数据校验。Java本版的机遇socket的聊天程序,课程学习资料和作业。附带详细代码说明文档。
Java P2P聊天服务端源码,通过NAT打洞技术,借助P2P服务端,采用客户端程序可以实现客户端点对点通讯
#自述##概述这是一个简单的P2P聊天项目。 主要是为了演示简单的P2P概念,但不包括分布式网络概念(你应该通过谷歌和维基百科改进自己)。 ##例子这是一个eclipse项目,你可以将它导入到eclipse中,然后导航到...