无法通过互联网从 PC 服务器接收 Android 上的 UDP 数据 [英] Unable to receive UDP data on Android from PC server over the Internet

查看:22
本文介绍了无法通过互联网从 PC 服务器接收 Android 上的 UDP 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在探索使用 Java 进行 UDP 数据包传输,以在 Android 上创建多人游戏.我使用通常的127.0.0.1"成功地在我的 Nexus 4 中交换了数据包,我也成功地在我的 PC 服务器和我的本地网络中的 Android 客户端之间交换了数据包.但是因为我希望我的游戏可以在 Internet 上玩,所以我希望我的 Android 客户端能够与我的 PC 服务器交换数据包,当它们不在同一个本地网络上时.这就是我挣扎的地方.

I am currently exploring UDP packet transmission in Java to create a multiplayer game on Android. I succeeded at exchanging packets within my Nexus 4 by using the usual "127.0.0.1" and I also succeeded at exchanging packets between my PC server and my Android client in my local network. But since I will want my game to be playable on the Internet, I want my Android client to be able to exchange packets with my PC server when they aren't on the same local network. This is where I am struggling.

我的设置:一台连接到我家互联网连接的 PC 服务器和一台连接到 3G 网络的 Nexus 4.

My setup : A PC server connected with my home Internet connection and a Nexus 4 connected with a 3G network.

首先,我的PC服务器开始监听10000端口,我的Android客户端打开一个socket,在10001端口接收服务器的数据包.然后,Android客户端向PC服务器发送一个数据包到它当前的公共地址173.246.12.125"" 在端口 10000 上.PC 服务器收到数据包并在端口 10001 上向发送方发送响应.但 Android 客户端从未收到响应.

First, my PC server starts listening on the port 10000 and my Android client opens a socket to receive server's packets on port 10001. Then, the Android client sends a packet to the PC server to its current public address "173.246.12.125" on port 10000. The PC server receives the packet and sends a response to the sender on port 10001. But the Android client never receives the response.

这是我的 PC 服务器代码:

Here is my PC server code :

public class UDPServer {
    private final static int SERVER_PORT = 10000;
    private final static int CLIENT_PORT = 10001;

    public static void main(String[] args) {
        InetAddress clientAddr = null;
        DatagramSocket socket = null;
        try {
            //Initializing the UDP server
            System.out.println(String.format("Connecting on %s...", SERVER_PORT));
            socket = new DatagramSocket(SERVER_PORT);
            System.out.println("Connected.");
            System.out.println("====================");
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        }

        while(true){
            try {
                //Listening
                byte[] buf = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                System.out.println("Listening...");
                socket.receive(packet);

                //Getting client address from the packet we received
                clientAddr = packet.getAddress();
                System.out.println("Received: '" + new String(packet.getData()).trim() + "' from "+clientAddr.toString());

                //Sending response
                byte[] message = ("Hello Android").getBytes();
                DatagramPacket response = new DatagramPacket(message, message.length, clientAddr, CLIENT_PORT);
                DatagramSocket clientSocket = new DatagramSocket();
                System.out.println("Sending: '" + new String(message) + "'");
                clientSocket.send(response);
                System.out.println("Response sent.");
                System.out.println("--------------------");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

这是我的 Android 客户端类:

And here are my Android client classes :

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new Receiver()).start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(new Client()).start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

public class Receiver implements Runnable {
    private final static int LISTENING_PORT = 10001;

    @Override
    public void run() {
        try {
            //Opening listening socket
            Log.d("UDP Receiver", "Opening listening socket on port "+LISTENING_PORT+"...");
            DatagramSocket socket = new DatagramSocket(LISTENING_PORT);
            socket.setBroadcast(true);
            socket.setReuseAddress(true);

            while(true){
                //Listening on socket
                Log.d("UDP Receiver", "Listening...");
                byte[] buf = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);
                Log.d("UDP", "Received: '" + new String(packet.getData()).trim() + "'");
            }
        } catch (Exception e) {
            Log.e("UDP", "Receiver error", e);
        }
    }
}

public class Client implements Runnable {
    private final static String SERVER_ADDRESS = "173.246.12.125";//public ip of my server
    private final static int SERVER_PORT = 10000;

    @Override
    public void run() {
        try {
            //Preparing the socket
            InetAddress serverAddr = InetAddress.getByName(SERVER_ADDRESS);
            DatagramSocket socket = new DatagramSocket();

            //Preparing the packet
            byte[] buf = ("Hello computer").getBytes();
            DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, SERVER_PORT);

            //Sending the packet
            Log.d("UDP", String.format("Sending: '%s' to %s:%s", new String(buf), SERVER_ADDRESS, SERVER_PORT));
            socket.send(packet);
            Log.d("UDP", "Packet sent.");
        } catch (Exception e) {
            Log.e("UDP", "Client error", e);
        }
    }
}

服务器的控制台正在显示客户端的 IP :

The server's console is showing the IP of the client :

Connecting on 192.168.1.126:10000...
Connected.
====================
Listening...
Received: 'Hello computer' from /204.48.72.68
Sending: 'Hello Android'
Response sent.
--------------------
Listening...

数据包似乎来自地址 204.48.72.68,但是如果我在 Android 上访问 whatismyip.com,它会显示 96.22.246.97...我不知道 204.48.72.68 来自哪里....

The packet seems to come from the address 204.48.72.68, but if I go on whatismyip.com on my Android, it shows me 96.22.246.97... I don't know where 204.48.72.68 is coming from...

我不确定问题是我的 Android 客户端上的侦听套接字不好还是 PC 服务器没有将响应发送到正确的地址.有人可以指出我做错了什么吗?

I am not sure if the problem is that my listening socket on my Android client is not good or if the PC server does not send the response to the correct address. Could someone points me what am I doing wrong?

谢谢

推荐答案

我遇到了类似的问题,但我使用的是 TCP 套接字而不是 UDP.我的热情是直接将文件发送到手机.在局域网中,这非常有效.当您的手机使用移动连接连接到互联网时,似乎无法将数据发送到侦听套接字.我在一些页面上读过(sry 不再有任何链接),移动电话上的传入连接被电信提供商阻止.我的解决方法是创建到服务器的传出连接并使用 tcp 套接字的双向可能性.也许您可以使用工作"数据报套接字与您的手机交换数据.这是我发现的一个例子:http://itucet.blogspot.de/2011/03/java-bidirectional-data-transfer-using.html

I came across a similar issue, but I was using TCP Sockets instead of UDP. My intense was sending files directly to a mobile. In LAN this worked pretty much. It appears, that's not possible to send data to listening sockets, when your phone is connected to internet using the mobile connection. I've read on some pages (sry dont have any links anymore), that incoming connections on a mobile phone is blocked by the telecommunications provider. My workaround was to create outgoing connections to the server and use the bidirectional possiblities of tcp sockets. Maybe you can use your "working" datagram socket, to exchange data with your mobile. Here is an example, which i had found: http://itucet.blogspot.de/2011/03/java-bidirectional-data-transfer-using.html

这篇关于无法通过互联网从 PC 服务器接收 Android 上的 UDP 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆