【问题标题】:Server not Receiving UDP Packet from Android服务器未从 Android 接收 UDP 数据包
【发布时间】:2015-05-02 23:13:53
【问题描述】:

我查看了其他一些看起来相似的文章,但是我找不到任何相关的文章并回答了这个问题。

我正在尝试将 UDP 数据包从 android 应用程序发送到外部服务器。

截至目前,数据包发送成功(代码完成且没有错误)但服务器没有收到数据包。

  1. 我知道UDP不能保证,所以作为临时修复,它会多次发送数据包以防万一。
  2. 当代码在本地计算机上时它可以工作,但是一旦它移动到应用程序它就停止接收。
  3. 我尝试了几个不同的端口号,效果相同
  4. 我尝试了几种不同的服务器程序,包括我知道的与计算机客户端一起工作但也无法正常工作的程序
  5. 我相信我拥有必要的权限(没有权限错误),但是如果我没有,请告诉我。当前所有权限如下:

    • 互联网
    • USE_CREDENTIALS
    • GET_ACCOUNTS
    • READ_PROFILE
    • READ_CONTACTS
    • 互联网
    • ACCESS_NETWORK_STATE

Android 客户端:

@Override
    protected void onResume() {
        super.onResume();
        // TODO: following is done onResume only because it does not save its data yet

        // check for internet first
        ConnectivityManager connMgr = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnected()) {
            // download and display plant data
            new downloadPlantDataTask().execute("169.234.79.98");
        } else {
            // display error
            TextView viewErrors = (TextView) findViewById(R.id.view_errors);
            viewErrors.setText("No internet connection...");
        }
    }

public String[] downloadPlantData(String ip) throws IOException {
        Vector<String> plantsNShit = new Vector<String>();
        TextView viewErrors = (TextView) findViewById(R.id.view_errors); // TODO: temp(?)

        // get datagram socket
        DatagramSocket socket = new DatagramSocket();

        // setup info for request
        byte[] buf = new byte[256];
        buf[0] = 1;
        InetAddress address = InetAddress.getByName(ip);
        DatagramPacket packet;

        while (true) {
            // send request
            for (int i = 0; i < 5; i++) {
                viewErrors.setText("sending packet"); // TODO: temp
                packet = new DatagramPacket(buf, buf.length, address, 60000);
                try {
                    socket.send(packet);
                    Log.i("Packet message", "packet sent"); // TODO: temp
                } catch (Exception e) {
                    Log.e("Packet error", e.getMessage());
                }
            }

            // get response
            packet = new DatagramPacket(buf, buf.length);
            socket.receive(packet);
            viewErrors.setText("packet received"); // TODO: temp

            // store response
            String received = new String(packet.getData(), 0, packet.getLength());
            if (received == "DONE")
                break;
            plantsNShit.add(received); // TODO: temporarily storing in vector
        }

        viewErrors.setText("finished");
        socket.close();
        return plantsNShit.toArray(new String[plantsNShit.size()]);
    }

服务器代码

import java.io.*;
import java.net.*;

public class DatagramServerThread extends Thread{

    protected DatagramSocket socket = null;
    protected BufferedReader in = null;
    protected boolean moreLines = true;

    public DatagramServerThread() throws IOException {
        this("DatagramServer");
    }

    public DatagramServerThread(String name) throws IOException {
        super(name);
        socket = new DatagramSocket(60000);

        try {
            in = new BufferedReader(new FileReader("pingas.txt"));
        } catch (FileNotFoundException e) {
            System.err.println("Couldn't open file. You dun messed up son.");
        }
    }

    public void run() {
        while (moreLines) {
            try {
                byte[] buf = new byte[256];
                // receive request
                System.out.println("waiting for packet");
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);
                System.out.println("packet received");

                // figure out response
                String dString = null;
                if (in == null)
                    dString = "DONE";
                else
                    dString = getNextLine();
                buf = dString.getBytes();

                // send the response
                InetAddress address = packet.getAddress();
                int port = packet.getPort();
                packet = new DatagramPacket(buf, buf.length, address, port);
                socket.send(packet);
                System.out.println("packet sent");
            } catch (IOException e) {
                e.printStackTrace();
                moreLines = false;
            }
        }
        socket.close();
    }

    protected String getNextLine() {
        String returnValue = null;
        try {
            if ((returnValue = in.readLine()) == null) {
                in.close();
                moreLines = false;
                returnValue = "DONE";
            }
        } catch (IOException e) {
            returnValue = "IOException occurred in server.";
        }
        return returnValue;
    }
}

*另外,如果我显示的代码太多或太少,或者违反任何其他规则和内容,请告诉我,这样我会变得更好。谢谢。

【问题讨论】:

  • 不要使用== 来比较字符串。使用String.equals().

标签: java android sockets networking udp


【解决方案1】:

两个项目:

  1. 假设您的代码确实有效,客户端和服务器都是 在同一台机器上,最有可能发生的是您的 数据包被您机器的防火墙阻止,因为您的 客户端(您的手机)现在正在从机器外部发出请求。

    不确定您使用的是什么操作系统(Windows、OS X、Linux?),但请 确保你进入防火墙设置,并打开相应的 端口 5673。

  2. 在您的客户端代码中,我没有看到它专门发送到 您的服务器正在侦听的相同端口。这也很重要。

【讨论】:

  • 1.我的计算机的防火墙当前已关闭并允许一切 2. 我相信它在“packet = new DatagramPacket(buf, buf.length, address, 60000);”中指定了端口(服务器实际上在那个端口上,我只是忘了更新它)但是我应该在其他地方声明端口吗?
  • 当您的 UDP 客户端代码在本地机器上成功运行时,它是在 Android 模拟器中,还是在纯 Java 程序中?
  • 它在一个普通的 Java 程序中运行
猜你喜欢
  • 2015-07-13
  • 1970-01-01
  • 2017-10-13
  • 2020-09-17
  • 1970-01-01
  • 2016-10-18
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多