0

我有一个用 C 语言编写的 UDP 服务器,它每 5 秒通过我的 LAN 在端口 3001 上广播 paquets。

我正在创建一个 android 应用程序作为 UDP 客户端,它正在侦听端口 3001(在 AsyncTask 线程中)并且它一直运行到接收()方法,在这个端口上似乎没有检测到数据。

这是我的代码:

private class ConnectionTask extends AsyncTask<Void, Integer, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... arg0) {

        String receivedString = "";

        byte[] receiveData = new byte[1024];

        DatagramSocket clientSocket;
        try {
            while(true){
                clientSocket = new DatagramSocket(5000);
                DatagramPacket receivePacket = new DatagramPacket(receiveData,
                        receiveData.length);
                clientSocket.receive(receivePacket);
                receivedString = new String(receivePacket.getData());
            }


        } catch (SocketException e) {
            Log.v("SocketExceptionOccured", e.toString());
            e.printStackTrace();
            //clientSocket.close();
        } catch (IOException e) {
            Log.v("IOExceptionOccured", e.toString());
            e.printStackTrace();
            //clientSocket.close();
        }

        Toast.makeText(getBaseContext(), receivedString, Toast.LENGTH_LONG)
                .show();

        return null;

    }

}

我用自己的设备测试我的代码以进行调试,使用 USB 电缆。

我已经使用在我的计算机上运行的简单 UDP 客户端(C 语言)测试了我的服务器,并且通信正常。

我不知道为什么这段代码不起作用。有人有想法吗?

谢谢,

4

3 回答 3

0

你永远不会离开while循环。您可能收到了消息,之后,循环会导致数据报套接字再次侦听。

于 2013-09-25T22:25:08.490 回答
0

不要每次在循环中创建和关闭套接字。首先创建它,然后关闭它。目前有一段时间内套接字不存在,因此发送给它的数据报会被丢弃:此外,每次关闭它时都会丢弃所有排队的数据报。

于 2013-09-25T23:31:06.927 回答
0

我有同样的问题。您需要在android清单中添加权限

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

还要在套接字中启用广播。

clientSocket.setBroadcast(true);

就像我之前提到的其他人一样,您的代码也永远不会离开 while 循环,因此它永远不会进入显示 toast 的行。请记住,您不能显示来自 doInBackground 的 Toast 消息,因为这是访问 UI 线程,您只能从 postExecute 和 preExecute 函数执行此操作。这将导致您的应用程序崩溃。要检查您收到的数据,您可以对其进行调试或记录。

你最终的 doInBackground 应该是这样的

@Override
protected Void doInBackground(Void... arg0) {

    String receivedString = "";

    byte[] receiveData = new byte[1024];

    DatagramSocket clientSocket;
    try {
        while(true){
            clientSocket = new DatagramSocket(5000);
            DatagramPacket receivePacket = new DatagramPacket(receiveData,
                    receiveData.length);
            clientSocket.setBroadcast(true);
            clientSocket.receive(receivePacket);
            receivedString = new String(receivePacket.getData());
            Log.i("Received String= "+receivedString);
        }


    } catch (SocketException e) {
        Log.v("SocketExceptionOccured", e.toString());
        e.printStackTrace();
        //clientSocket.close();
    } catch (IOException e) {
        Log.v("IOExceptionOccured", e.toString());
        e.printStackTrace();
        //clientSocket.close();
    } finally{
        if(clientSocket!=null){
           clientSocket.close();
        }
    }

    return null;

}

现在,当您检查日志时,您应该能够看到收到的字符串的值。

于 2015-11-27T02:44:09.863 回答