首页 文章

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

提问于
浏览
3

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

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

我面临的问题是移动网络和我的wifi网络之间或2移动网络之间的通信 . 当我从移动网络发送消息时,我无法在我的应用程序中收到它,但可以在NetCat应用程序中的同一端口上收听 .

谁能在这方面帮助我?

Sending

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");
    }

Receiving

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");
        }

Port Forwarding via 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

    虽然这里的代码似乎很好,但是你的方法存在一些问题 .

    • 大多数移动网络do not support UPnP port forwarding .

    • 根据您的网络拓扑(您无法始终控制),在面向公众的地址后面可能会有两层或更多层NAT路由 . 第一层可能支持UPnP,但其他层可能不支持 .

    您可能希望尝试使用 UDP hole punching technique 进行NAT遍历,而不是UPnP,并解释herehere .

    虽然它需要一个公共服务器来协调'peer introduction',但这种技术在今天高度分散的互联网中得到的支持远远超过其他技术,如UPnP端口转发,特别是在处理移动网络或多层NAT路由时 .

    它基本上归结为UDP是一种无连接协议(与TCP不同),因此当两个对等体(NAT路由器后面)同时向对方发送UDP消息时,它们各自的NAT路由器认为来自另一个对等体的入站请求是响应原始传出数据包 .

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

相关问题