Android UDP对等网络通信(无服务器)

时间:2018-06-06 18:57:55

标签: android sockets udp datagram

我是Android网络的新手,在没有服务器的情况下处理项目p2p。

最初我必须在2台设备之间进行通信。我通过DataGramSocket实现了在不同NATS内部和后面的两个wifi网络之间的成功通信,并使用library通过Upnp进行端口转发。

我面临的问题是移动网络和我的wifi网络之间或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 :(得分:0)

虽然这里的代码看起来不错,但是您的方法存在一些问题。

  1. 大多数移动网络do not support UPnP port forwarding
  2. 根据您的网络拓扑结构(您始终无法控制),在面向公众的地址后面可能会有两层或多层NAT路由。第一层可能支持UPnP,但其他层可能不支持。

您可能要尝试使用 UDP孔打孔技术代替UPnP,以进行herehere所解释的NAT遍历。

尽管它需要一个公开可用的服务器来协调“对等引入”,但在当今高度分散的互联网中,此技术比其他技术(如UPnP端口转发)更受支持(92-96% of peers),尤其是在处理移动设备时。网络或多层NAT路由。

它基本上可以归结为UDP是一种无连接协议(与TCP不同),因此,当两个对等点(在NAT路由器之后)相互互相发送UDP消息时,它们各自的NAT路由器会被“诱骗”相信来自其他对等方的入站请求是对原始传出数据包的响应。

此外,如果您担心服务器的运行成本,那么如今,如果您在主要云供应商(AWS,Microsoft,Google,AliCloud等)之间轮换成员资格,则可以获得多年的免费云VM服务器使用率。 。