【问题标题】:Android UDP peer to peer networking communication (without server)Android UDP 点对点网络通信(无服务器)
【发布时间】:2018-11-16 13:40:57
【问题描述】:

我是 Android 网络的新手,正在从事没有服务器的 p2p 项目。

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

我面临的问题是移动网络和我的 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))
    {

    }
}

【问题讨论】:

    标签: android sockets udp datagram


    【解决方案1】:

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

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

    除了 UPnP,您可能想尝试 UDP 打洞技术 用于 NAT 穿越,解释了 herehere

    虽然它需要一个公开可用的服务器来协调“对等介绍”,但在当今高度分散的互联网中,这种技术得到了更广泛的支持 (92-96% of peers),而不是其他技术,例如 UPnP 端口转发,尤其是在处理移动网络或多层 NAT 路由。

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

    此外,如果您担心运行服务器的成本,现在如果您在主要云供应商(AWS、微软、谷歌、阿里云......)之间轮换会员资格,您可以获得多年的免费云虚拟机服务器使用权。 .

    【讨论】:

      猜你喜欢
      • 2022-12-16
      • 1970-01-01
      • 1970-01-01
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 2016-02-07
      • 1970-01-01
      相关资源
      最近更新 更多