2015-03-22 8 views
1

Так что я пытаюсь реализовать сквозное прохождение 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(); , то мобильный говорит, что он подключен. если я оставлю строки, мобильник получит сообщение об ошибке, когда одноранговое соединение сбросит соединение.

Однако в любом случае ноутбук, похоже, вообще не реагирует. Если я использую альтернативу серверного сокета вместо того, чтобы пытаться подключиться к ноутбуку, мобильный компьютер не пытается подключиться в качестве времени соединения.

+0

Обновление: потребовалось некоторое время, но я понял, что NAT, предоставляющий мой мобильный телефон и USB-модем с IP-адресами, имеет несколько общедоступных IP-адресов, поэтому оба устройства фактически находятся за одним и тем же NAT и в той же частной сети. Поэтому завтра я собираюсь получить SIM-карту другого оператора и посмотреть, действительно ли работает дырокол. – user3774221

ответ

0

Похоже, у вас есть хорошее решение для поиска правильных общедоступных адресов двух устройств.Однако даже с этой информацией многие (или, может быть, даже самые) мобильные сети все равно не смогут подключать входящие TCP-соединения к мобильному устройству.

Некоторые из них будут иметь разные ограничения для разных типов устройств, поэтому, возможно, вы иногда работаете с модемным широкополосным модемом, но никогда с телефоном. Эти различия могут быть даже просто потому, что модем и телефонные соединения настроены по-разному в сетях операторов (например, используют разные APN с разными правилами).

Вы, скорее всего, знаете, но вы все равно можете общаться друг с другом, используя сервер в качестве точки «реле» в середине - это, очевидно, добавляет сложности на стороне сервера к вашему решению, но у него есть преимущество в том, большинство операторов. Подход выглядит примерно так:

  • ноутбуков connectes на сервер
  • Мобильного connectes на сервер
  • Laptop запрашивает сервер для списка подключенных устройств и мобильного
  • Laptop «обнаруживает» посылает сообщение для мобильных устройств. Он фактически отправляет сообщения на сервер с указанием, что он должен быть отправлен на мобильный.
  • Сервер уведомляет мобильную связь о том, что для нее доступно сообщение (например, с помощью какого-либо уведомления о сообщениях, например Google Cloud Messaging, или просто с помощью опроса устройств, чтобы узнать, есть ли у них какие-либо сообщения).
  • Мобильный получает сообщения с сервера.
+0

Привет, спасибо за ответ. , так что теперь я могу последовательно подключаться от мобильного к ноутбуку. Каждый раз он будет подключаться на мобильной стороне. Но сторона ноутбука не узнает об этом. Есть ли способ открыть сокет сервера на том же порту, пытаясь также подключиться к нему? Я не вижу, как мобильный телефон может подключиться к natted IP и портам ноутбука, если ноутбук не пытается подключиться. Я использую sim мобильного телефона в USB-модемом. Будет ли использовать тот же APN, что и на моем телефоне? – user3774221

 Смежные вопросы

  • Нет связанных вопросов^_^