Android UDP одноранговая сетевая связь (без сервера) - PullRequest
0 голосов
/ 06 июня 2018

Я новичок в сети Android и работаю над проектом p2p без сервера.

Изначально я должен установить связь между двумя устройствами.Я достиг успешного взаимодействия между двумя сетями Wi-Fi внутри и за различными NAT через DataGramSocket с переадресацией портов через Upnp с использованием библиотеки .

Проблема, с которой я сталкиваюсь, - это когда связь между мобильной сетью и моей сетью Wi-Fiили между 2 мобильными сетями.Когда я отправляю сообщение из мобильной сети, я не могу получить его в своем приложении, но могу прослушивать тот же порт в приложении NetCat.

Кто-нибудь может мне помочь в этом отношении?

Отправка

try {
        socket = new DatagramSocket(dstPort);
        address = InetAddress.getByName(dstAddress);
        socket.connect(address,dstPort);
        socket.setBroadcast(false);
        socket.setReuseAddress(true);
        //sendState("Socket Status "+socket.isConnected());
        String sendString = msg;
        byte[] sendData = sendString.getBytes("UTF-8");
        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
                address, dstPort);
        socket.send(sendPacket);
        //sendState("Sent = "+sendData);

    } catch (SocketException e) {
        //sendState(e.getLocalizedMessage());
        sendState("SocketException");
    }

Получение

try {
            socket = new DatagramSocket(dstPort);
            address = InetAddress.getByName(dstAddress);
            // send request
            byte[] buf = new byte[4096];
            DatagramPacket packet =
                    new DatagramPacket(buf, buf.length, address, dstPort);
            socket.connect(address,dstPort);
            socket.setBroadcast(false);
            socket.setReuseAddress(true);
            socket.receive(packet);
            String line = new String(packet.getData(), 0, packet.getLength());
            sendState(line);
            //sendState("Reached3");


        } catch (SocketException e) {
            //sendState(e.getLocalizedMessage());
            sendState("SocketException");
        }

Переадресация портов через UpNp

   protected void setUpnp(int port_)
{
    if(Connectivity.isConnectedWifi(this)) {
        String myIp = getIpAddress();
        int port = port_;

        //creates a port mapping configuration with the external/internal port, an internal host IP, the protocol and an optional description
        PortMapping[] desiredMapping = new PortMapping[2];
        desiredMapping[0] = new PortMapping(port, myIp, PortMapping.Protocol.TCP);
        desiredMapping[1] = new PortMapping(port, myIp, PortMapping.Protocol.UDP);

        //starting the UPnP service
        UpnpService upnpService = new UpnpServiceImpl(new AndroidUpnpServiceConfiguration());
        RegistryListener registryListener = new PortMappingListener(desiredMapping);
        upnpService.getRegistry().addListener(registryListener);
        upnpService.getControlPoint().search();
    }
    else if(Connectivity.isConnectedMobile(this))
    {

    }
}

1 Ответ

0 голосов
/ 13 декабря 2018

Хотя код здесь выглядит нормально, с вашим подходом есть пара проблем.

  1. Большинство мобильных сетей не поддерживают переадресацию портов UPnP .
  2. В зависимости отв топологии вашей сети (которую вы не всегда можете контролировать) может быть два или более уровней NAT-маршрутизации за вашим публичным адресом.Ближайший уровень может поддерживать UPnP, но другие уровни могут не поддерживать.

Вместо UPnP вы можете попробовать метод дырокола UDP UDP для прохождения NAT, объясненного здесь и здесь .

Хотя для координации «однорангового представления» требуется общедоступный сервер, этот метод поддерживается гораздо шире ( 92-96% пиров ) в сегодняшнем сильно фрагментированном Интернете, чем другие методы, такие как переадресация портов UPnP, особенно при работе с мобильными сетями или несколькими уровнями маршрутизации NAT.

В основном все сводится к тому, что UDP является протоколом без установления соединения (в отличие от TCP), поэтому, когда два узла (за маршрутизаторами NAT) отправляют друг другу сообщение UDP , соответствующие маршрутизаторы NAT«обманным путем» поверил, что входящий запрос от другого узла является ответом на исходящий исходящий пакет.

Кроме того, если вас беспокоит стоимость запуска сервера, в эти дни вы можете получить много лет бесплатного использования облачных ВМ-серверов, если будете менять членство среди основных поставщиков облачных технологий (AWS, Microsoft, Google, AliCloud)...).

...