Так что я пытаюсь реализовать сквозное прохождение TCP между двумя мобильными устройствами (мобильным и мобильным мобильным телефоном Android с мобильным широкополосным модемом USB). Я использую другой ноутбук, подключенный к Wi-Fi, чтобы действовать как сервер.TCP-соединение не выполняется после пробивки отверстий
Сначала я получил ноутбук для подключения к серверу, на котором отображается его общедоступный IP-адрес и номер порта NAT, который видит сервер.
try{
System.out.println("connect to server");
Socket connectToServer = new Socket();
System.out.println("49");
connectToServer.bind(new InetSocketAddress(myIPAddress.getHostAddress(), myPort));
System.out.println("51");
connectToServer.connect(new InetSocketAddress(serverIPAddress.getHostAddress(), serverPort));
System.out.println("connected to server: " + connectToServer);
connectToServer.close();
}
catch (Exception e){
System.out.println("Exception 1 :" + e.toString());
//connectToServer.close();
}
Мобильный телефон делает то же самое, поэтому я вижу его общедоступный IP-адрес и номер порта NAT. Ноутбук и мобильный телефон закрывают свои соединения с сервером.
Ноутбук затем подключается к мобильному телефону, используя тот же локальный IP-адрес и номер порта (который он использовал для подключения к серверу) и используя общедоступный IP-адрес мобильного телефона и номер порта NAT.
try{
Socket punchSocket = new Socket();
System.out.println("33");
punchSocket.bind(new InetSocketAddress(myIPAddress.getHostAddress(), myPort));
System.out.println("35");
punchSocket.connect(new InetSocketAddress(mobileAddress.getHostAddress(), mobilePort));
punchSocket.close();
}
catch(Exception e){
System.out.println("exception 2 caught " + e.toString());
}
А поскольку мобильный телефон находится за пределами nat, время соединения заканчивается, и я получаю исключение.
try{
Socket mobileSocket = new Socket();
System.out.println("105");
mobileSocket.bind(new InetSocketAddress(myIPAddress.getHostAddress(), myPort));
System.out.println("124");
mobileSocket.connect(new InetSocketAddress(mobileAddress.getHostAddress(), mobilePort));
System.out.println("connection made: " + mobileSocket);
mobileSocket.close();
}
catch(Exception e){
System.out.println("exception 2 caught " + e.toString());
}
И наконец, я пытаюсь снова подключиться к мобильному телефону. Пока ноутбук пытается подключиться к мобильному телефону, я также инициирую подключение с мобильного телефона. Используя тот же IP-адрес и порт (мобильный, используемый для подключения к серверу), я подключаюсь к общедоступным IP-портам и портам ноутбука.
но и мобильный, и ноутбук пытается подключить только время ожидания.
Вместо того, чтобы просто пытаться подключиться с ноутбука на мобильный во второй раз, я также пытался иметь ноутбук слушать соединение:
ServerSocket welcomeSocket = new ServerSocket(myPort, 50, myIPAddress);
welcomeSocket.setSoTimeout(5);
System.out.println("Start listening for mobile to connect");
while(true){
try{
Socket newsock = welcomeSocket.accept();
System.out.println("connection made: " + newsock);
}
catch(Exception e) {
System.out.println("exception 4 caught " + e.toString());
}
}
Но это не сработало. Понятия не имею почему. Есть ли способ проверить, сможет ли NAT моего мобильного провайдера разрешить пробой?
Это, как я соединяю с мобильного телефона:
try {
Log.d("stop", "line 64");
InetAddress serverIPAddress = InetAddress.getByName(serverIP);
InetAddress myIPAddress = InetAddress.getByName(myIP); //InetAddress.getLocalHost();
Log.d("stop", "line");
Log.d("localHost: ", myIPAddress.getHostAddress());
Socket clientSocket = new Socket();
Log.d("stop", "line 70");
clientSocket.bind(new InetSocketAddress(myIPAddress.getHostAddress(), myPort));
Log.d("stop", "line 72");
clientSocket.connect(new InetSocketAddress(serverIPAddress.getHostAddress(), serverPort));
Log.d("stop", "line 74");
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
receivedMessage = inFromClient.readLine();
Log.d("stop", "line 78");
clientSocket.close();
//Toast.makeText(this, "socket connected", Toast.LENGTH_SHORT).show();
return receivedMessage; //receivedMessage;
} catch (IOException e) {
//Toast.makeText(this, "socket caughyt", Toast.LENGTH_SHORT).show();
e.printStackTrace();
error1 = "no Server";
Log.d("error", error1 + e.getMessage());
}
Я провел большую часть сегодняшнего дня, пытаясь понять это. Когда serverocket используется на ноутбуке, ошибка на мобильном устройстве - это таймаут. Он случайно работал однажды прошлой ночью (1 час), и я лег спать. Сегодня не работает. Не знаю, почему нет. Любая помощь будет оценена по достоинству.
EDIT:
Хорошо, так что теперь после того, как ноутбук пытается соединиться с мобильным и выходит из строя (а затем постоянно пытается подключиться к мобильному-не по сценарию сокет-сервера), мобильные попытки подключения к компьютеру и проходит. Если я удалю строки: BufferedReader inFromClient = new BufferedReader (новый InputStreamReader (clientSocket.getInputStream())); полученоMessage = inFromClient.readLine(); , то мобильный говорит, что он подключен. если я оставлю строки, мобильник получит сообщение об ошибке, когда одноранговое соединение сбросит соединение.
Однако в любом случае ноутбук, похоже, вообще не реагирует. Если я использую альтернативу серверного сокета вместо того, чтобы пытаться подключиться к ноутбуку, мобильный компьютер не пытается подключиться в качестве времени соединения.
Обновление: потребовалось некоторое время, но я понял, что NAT, предоставляющий мой мобильный телефон и USB-модем с IP-адресами, имеет несколько общедоступных IP-адресов, поэтому оба устройства фактически находятся за одним и тем же NAT и в той же частной сети. Поэтому завтра я собираюсь получить SIM-карту другого оператора и посмотреть, действительно ли работает дырокол. – user3774221