假设有两台分别处于各自的私有网络中的主机:A和B;N1和N2是两个NAT设备;S是一个使用了一个众所周知的、从全球任何地方都能访问得搏拍含到的IP地址的公共服基笑务器
10年积累的成都网站建设、成都网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计制作后付款的网站建设流程,更有昆玉免费网站建设让你可以放心的选择与我们合作。
步骤一:A和B分别和S建立UDP连贺纤接;NAT设备N1和N2创建UDP转换状态并分配临时的外部端口号
步骤二:S将这些端口号传回A和B
步骤三:A和B通过转换好的端口直接联系到对方的NAT设备;NAT设备则利用先前创建的转换状态将分组发往A和B
源码已发送请查收
JAVA贺新态知年-自己动手做QQ(P2P聊天工具含源码) - Dreamcode ~ ...
区袭闭答块拍慧链中的消息传播离不p2p通信 java实现一个简单的p2p通信demo工具: idea jdk1.8 maven1 : idea新建maven项...
在JAVA中,发送和接收多播信息的方法:
发送多播信息需经历步骤
确定发送的具体信息内容
String msg = "Hello";
选用专门为多播指定的D类IP地址(224.0.0.1到239.255.255.255),创建一个多播组
InetAddress group = InetAddress.getByName("228.5.6.7");
使用指定的端口(一般选1024以上的端口号)建立多播套接字
MulticastSocket s = new MulticastSocket(6789);
加入多播组
s.joinGroup(group);
创建一个数据报封装多播信息
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
group, 6789);
发送
s.send(hi);
接收多播信息的步骤
开辟接收缓冲区
byte[] buf = new byte[1000];
创建接收数据报
DatagramPacket recv = new DatagramPacket(buf, buf.length);
接收
s.receive(recv);
注意:以上发送和接收程序在同一个文件中实现,若在不同文件中实现则应分别定义多播套接字并加入多播组。
3.与已知IP和端口的端点通信
在互联网上主要采用TCP和UDP来实现两点之间的通信。采用TCP可可靠传送信息,但花费时间较多;采用UDP可快速传递信息,但不能保证可靠传递。
JAVA实现TCP通信的方法 :
利用Socket(InetAddress addr, int port)和 Socket(String host, int port),创建客户端套接字,利用ServerSocket(int port)创建服务器端套接字,port端口就是服务器监听连接请求的端口,通过调用accept()返回一个最近创建的Socket对象,该Socket对象绑定了客户程序的IP地址或端口号。通过调用Socket的 getInputStream()方法获得输入流读传送轮伍来的信息,也可能通过调用Socket的 getOutputStream()方法获得输出流来发送消息。
JAVA实现UDP通信的方法 :
使用DatagramPacket(byte [] buffer, int length, InetAddress addr, int port) 确定数据包数组、数组的长度、腊扒或数据包的地址和端口信息。使用DatagramSocket()创建客户端套接字,而服务器端则采用DatagramSocket(int port),调用send(DatagramPacket dgp)和 receive(DatagramPacket dgp)来发送和接收数据包。本文设计的程序采用UDP。
P2P(Peer-to-Peer 端到端)模型是与C/S(客户/服务器)模型相对应。基于C/S的用户间通信需要由服务器中转,在C/S中的服务器故障将导致整个网络通信的瘫痪此卜。。而基于P2P的用户间通信则是直接通信,去掉了服务器这一层,带来的显著优点是通信时没有单一的失败点,一个用户的故障不会影响整个P2P网络。本文提供了一种用JAVA实现P2P网络通信的方法。
程序分Server和Client
服务器端打开侦听的端口,一有客户端连衡昌接就创建两个新的线程来负责这个连接
一个负责客户端发送的信息(ClientMsgCollectThread 类),
另一个负责老拦薯通过该Socket发送数据(ServerMsgSendThread )
Server.java代码如下:
/*
* 创建日期 2009-3-7
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package faue.MutiUser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java点虐 .ServerSocket;
import java点虐 .Socket;
/**
* 服务器端
*
* @author Faue
*/
public class Server extends ServerSocket {
private static final int SERVER_PORT = 10000;
/**
* 构造方法,用于实现连接的监听
*
* @throws IOException
*/
public Server() throws IOException {
super(SERVER_PORT);
try {
while (true) {
Socket socket = super.accept();
new Thread(new ClientMsgCollectThread(socket), "getAndShow"
+ socket.getPort()).start();
new Thread(new ServerMsgSendThread(socket), "send"
+ socket.getPort()).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
new Server();
}
/**
* 该类用于创建接收客户端发来的信息并显示的线侍者程
*
* @author Faue
* @version 1.0.0
*/
class ClientMsgCollectThread implements Runnable {
private Socket client;
private BufferedReader in;
private StringBuffer inputStringBuffer = new StringBuffer("Hello");
/**
* 得到Socket的输入流
*
* @param s
* @throws IOException
*/
public ClientMsgCollectThread(Socket s) throws IOException {
client = s;
in = new BufferedReader(new InputStreamReader(client
.getInputStream(), "GBK"));
}
public void run() {
try {
while (!client.isClosed()) {
inputStringBuffer.delete(0, inputStringBuffer.length());
inputStringBuffer.append(in.readLine());
System.out.println(getMsg(inputStringBuffer.toString()));
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
}
}
/**
* 构造显示的字符串
*
* @param line
* @return
*/
private String getMsg(String line) {
return client.toString() + " says:" + line;
}
}
/**
* 该类用于创建发送数据的线程
*
* @author Faue
* @version 1.0.0
*/
class ServerMsgSendThread implements Runnable {
private Socket client;
private PrintWriter out;
private BufferedReader keyboardInput;
private StringBuffer outputStringBuffer = new StringBuffer("Hello");
/**
* 得到键盘的输入流
*
* @param s
* @throws IOException
*/
public ServerMsgSendThread(Socket s) throws IOException {
client = s;
out = new PrintWriter(client.getOutputStream(), true);
keyboardInput = new BufferedReader(new InputStreamReader(System.in));
}
public void run() {
try {
while (!client.isClosed()) {
outputStringBuffer.delete(0, outputStringBuffer.length());
outputStringBuffer.append(keyboardInput.readLine());
out.println(outputStringBuffer.toString());
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
}
}
}
}
客户端:
实现基于IP地址的连接,连接后也创建两个线程来实现信息的发送和接收
/*
* 创建日期 2009-3-7
*
*/
package faue.MutiUser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java点虐 .Socket;
/**
* 客户端
*
* @author Faue
*/
public class Client {
private Socket mySocket;
/**
* 创建线程的构造方法
*
* @param IP
* @throws IOException
*/
public Client(String IP) throws IOException {
try {
mySocket = new Socket(IP, 10000);
new Thread(new ServerMsgCollectThread(mySocket), "getAndShow"
+ mySocket.getPort()).start();
new Thread(new ClientMsgSendThread(mySocket), "send"
+ mySocket.getPort()).start();
} catch (IOException e) {
//e.printStackTrace();
System.out.println("Server.IP:" + IP
+ " port:10000 can not be Connected");
}
}
public static void main(String[] args) throws IOException {
try {
new Client(args[0]);
} catch (Exception e) {
System.out.println("输入的IP地址错误");
}
}
/**
* 该类用于创建接收服务端发来的信息并显示的线程
*
* @author Faue
* @version 1.0.0
*/
class ServerMsgCollectThread implements Runnable {
private Socket client;
private BufferedReader in;
private StringBuffer inputStringBuffer = new StringBuffer("Hello");
/**
* 得到Socket的输入流
*
* @param s
* @throws IOException
*/
public ServerMsgCollectThread(Socket s) throws IOException {
client = s;
in = new BufferedReader(new InputStreamReader(client
.getInputStream(), "GBK"));
}
public void run() {
try {
while (!client.isClosed()) {
inputStringBuffer.delete(0, inputStringBuffer.length());
inputStringBuffer.append(in.readLine());
System.out.println(getMsg(inputStringBuffer.toString()));
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
System.exit(0);
}
}
/**
* 构造输入字符串
*
* @param line
* @return
*/
private String getMsg(String line) {
return client.toString() + " says:" + line;
}
}
/**
* 该类用于创建发送数据的线程
*
* @author Faue
* @version 1.0.0
*/
class ClientMsgSendThread implements Runnable {
private Socket client;
private PrintWriter out;
private BufferedReader keyboardInput;
private StringBuffer outputStringBuffer = new StringBuffer("Hello");
/**
* 得到键盘的输入流
*
* @param s
* @throws IOException
*/
public ClientMsgSendThread(Socket s) throws IOException {
client = s;
out = new PrintWriter(client.getOutputStream(), true);
keyboardInput = new BufferedReader(new InputStreamReader(System.in));
}
public void run() {
try {
while (!client.isClosed()) {
outputStringBuffer.delete(0, outputStringBuffer.length());
outputStringBuffer.append(keyboardInput.readLine());
out.println(outputStringBuffer.toString());
}
out.println("--- See you, bye! ---");
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
System.exit(0);
}
}
}
}
如果对您有帮助,请记得采纳为满意答案,谢谢!祝您生活愉快!
vaela