Существует 3 секции, серверная часть, клиент A для ПК и клиент B для Android.
Логика:
1. Когда клиент A и B подключаются к серверу, они будут уведомлены о другом ip и порту.
2. Затем A пробивает отверстие для B и сообщает серверу, что он готов для приема от B.
3. сервер сообщит B, что A готов.
4. Тогда B будет отправить сообщение A.Как заставить его работать на p2p?
Это только простой тест, тест окружающей среды являются:
1. Сервер имеет публичный IP и порт
2. Клиент А и Клиент B находятся в другой NAT
Код не работает. Два коллеги не могут общаться друг с другом. Как заставить двух равных общаться? Я буду благодарен за каждый совет.
[изменить]
Спасибо, @kha. Первый раз я публикую здесь. Я подробно расскажу о процессе.
1. Никаких исключений из этих трех разделов. У меня нет ошибок.
2. Два клиента могут подключаться к серверу и получать IP-адрес и порт другого пользователя с сервера.
3. Я отключил брандмауэр для Windows. Для android я не знаю, как это сделать.
4. Два клиента просто не могут общаться, никаких других исключений.
5. Я новичок в P2P, поэтому я хочу больше помочь в поиске проблемы.
сервера код сторона:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class Main {
static EndPoint endPoint;
static EndPoint endPoint2;
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) {
try {
DatagramSocket server = new DatagramSocket(5050);
boolean isSend = false;
while (true) {
System.out.println("start receiving...");
EndPoint ep = receiveMessage(server);
if (endPoint == null) {
System.out.println("endPoint initialized");
endPoint = ep;
} else if (endPoint2 == null) {
System.out.println("endPoint2 initialized");
endPoint2 = ep;
} else {
if (!isSend) {//when A and B all connect to server, they will be notified another's ip and port
isSend = true;
System.out.println("send to each other");
sendEndPointMessage(server, endPoint, endPoint2);
sendEndPointMessage(server, endPoint2, endPoint);
} else {
if ("5".equals(ep.message)) {// client A is ready
System.out.println("client A is ready");
sendMessage(server, "6", endPoint2);// send B message that A is reay
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void sendEndPointMessage(DatagramSocket server, EndPoint epReceive, EndPoint epContent) {
try {
String sendStr = epContent.host + ";" + epContent.port;
byte[] sendBuf = sendStr.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, epReceive.addr, epReceive.port);
server.send(sendPacket);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void sendMessage(DatagramSocket server, String msg, EndPoint ep) {
try {
byte[] sendBuf = msg.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, ep.addr, ep.port);
server.send(sendPacket);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static EndPoint receiveMessage(DatagramSocket server) {
try {
byte[] recvBuf = new byte[1024];
DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
server.receive(recvPacket);
String recvStr = new String(recvPacket.getData(), 0, recvPacket.getLength());
int port = recvPacket.getPort();
InetAddress addr = recvPacket.getAddress();
System.out.println("EndPoint: host:" + recvPacket.getAddress() + ", port:" + port + ", message:" + recvStr);
EndPoint endPoint = new EndPoint(addr, port, recvStr);
return endPoint;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
static class EndPoint {
InetAddress addr;
String host;
int port;
String message;
public EndPoint(String host, int port, String message) {
this.host = host;
this.port = port;
this.message = message;
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public EndPoint(InetAddress host, int port, String message) {
this.host = host.getHostAddress();
this.port = port;
this.message = message;
addr = host;
}
}
}
Клиент A для ПК:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class Main {
public static String serverAddr = "xxx.xxx.xxx.xx";
public static int serverPort = 5050;
public static String peerIP;
public static int peerPort;
/**
* @param args
*/
public static void main(String[] args) {
try {
final DatagramSocket client = new DatagramSocket();
sendMessage(client, "1", serverAddr, serverPort);
while (true) {
System.out.println("start receiving...");
String recvStr = receiveMessage(client);
if ("3".equals(recvStr)) {
sendMessage(client, "4", peerIP, peerPort);
} else {
String[] peer = recvStr.split(";");
if (peer.length > 1) {// received peer ip and port
peerIP = peer[0];
peerPort = Integer.parseInt(peer[1]);
sendMessage(client, "4", peerIP, peerPort);//punch a hole for client B
sendMessage(client, "5", serverAddr, serverPort);//tell server I am ready
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
sendMessage(client, "4", peerIP, peerPort);//keep punch a hole for client B
sendMessage(client, "5", serverAddr, serverPort);//keep telling server I am ready
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
} else {
if ("7".equals(recvStr)) {// received from client B
sendMessage(client, "got from android", peerIP, peerPort);
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static String receiveMessage(final DatagramSocket client) {
try {
byte[] recvBuf = new byte[1024];
DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
client.receive(recvPacket);
String recvStr = new String(recvPacket.getData(), 0, recvPacket.getLength());
String ip = recvPacket.getAddress().getHostAddress();
int port = recvPacket.getPort();
System.out.println("received from: host:" + ip + ", port:" + port + ", content:" + recvStr);
return recvStr;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static void sendMessage(final DatagramSocket client, String sendStr, String ip, int port) {
try {
System.out.println("send out: host:" + ip + ", port: " + port + ", message:" + sendStr);
byte[] sendBuf;
sendBuf = sendStr.getBytes();
InetAddress addr = InetAddress.getByName(ip);
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, addr, port);
client.send(sendPacket);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client B для Android:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
public String serverAddr = "xxx.xxx.xxx.xx";
public int serverPort = 5050;
public String peerIP;
public int peerPort;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.connectServer).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
connectServer();
}
}).start();
}
});
}
private void connectServer() {
try {
DatagramSocket client = new DatagramSocket();
sendMessage(client, "2", serverAddr, serverPort);
while (true) {
System.out.println("start receiving...");
String recvStr = receiveMessage(client);
String[] peer = recvStr.split(";");
if (peer.length > 1) {// received peer ip and port
peerIP = peer[0];
peerPort = Integer.parseInt(peer[1]);
} else {
if ("6".equals(recvStr)) {//received from server that client A is ready
sendMessage(client, "7", peerIP, peerPort); // send message to client A
}
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private String receiveMessage(DatagramSocket client) throws IOException {
try {
byte[] recvBuf = new byte[1024];
DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
client.receive(recvPacket);
String ip = recvPacket.getAddress().getHostAddress();
int port = recvPacket.getPort();
String recvStr = new String(recvPacket.getData(), 0, recvPacket.getLength());
System.out.println("received from: host:" + ip + ", port:" + port + ", content:" + recvStr);
return recvStr;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void sendMessage(DatagramSocket client, String sendStr, String ip, int port) {
try {
System.out.println("send out: host:" + ip + ", port:" + port + ", mesasge:" + sendStr);
byte[] sendBuf;
sendBuf = sendStr.getBytes();
InetAddress addr = InetAddress.getByName(ip);
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, addr, port);
client.send(sendPacket);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Объясните, что вы подразумеваете под «нерабочим». – kingdamian42
@ kingdamian42 изменен, не работает означает, что два сверстника не могут общаться друг с другом. –
Какая часть не работает? Какие ошибки вы получаете? Могут ли они подключиться к вашему серверу и получить IP-адреса друг друга? Есть ли проблемы с брандмауэром? Вы получаете сетевые исключения? Вы пытались сузить проблему и изолировать причину? – kha