简体   繁体   English

Android 3.2:接收UDP数据包不起作用?

[英]Android 3.2: Receive UDP packets does not work?

I am programming an Android tablet app. 我正在编写一个Android平板电脑应用程序。 It communicates via UDP messages (13 bytes data each). 它通过UDP消息(每个13字节数据)进行通信。 Sending these packets works correctly. 发送这些数据包正常工作。 But when I try to receive unicast UDP packets on port 15731 (and on other ports as well), it always returns IOException. 但是,当我尝试在端口15731(以及其他端口)上接收单播UDP数据包时,它总是返回IOException。 That's what my code looks like (receiveUDP runs cyclic). 那就是我的代码(receiveUDP循环运行)。

public void receiveUDP() {
    byte[] buffer = new byte[13];
    try {
        DatagramPacket dataIn = new DatagramPacket(buffer, buffer.length);
        DatagramSocket recSocket = new DatagramSocket(15731);
        recSocket.setSoTimeout(1000);
        recSocket.receive(dataIn);
        Log.i("receiveUDP", "UDP Message received: " + buffer.toString());
        recSocket.close();
    } catch (IOException e) {
        Log.i("receiveUDP", "IOException");
    }
    ;
}

In the Android Manifest I made the following permissions: 在Android清单中,我具有以下权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

The e.printfStackTrace() command turns out the following: e.printfStackTrace()命令得出以下结果:

11-17 14:34:05.130: WARN/System.err(25961): java.net.BindException: Address already in use
11-17 14:34:05.140: WARN/System.err(25961):     at org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
11-17 14:34:05.140: WARN/System.err(25961):     at dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:275)
11-17 14:34:05.140: WARN/System.err(25961):     at org.apache.harmony.luni.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:77)
11-17 14:34:05.140: WARN/System.err(25961):     at java.net.DatagramSocket.createSocket(DatagramSocket.java:190)
11-17 14:34:05.140: WARN/System.err(25961):     at java.net.DatagramSocket.<init>(DatagramSocket.java:74)
11-17 14:34:05.140: WARN/System.err(25961):     at com.example.MyService.onCreate(MyService.java:78)
11-17 14:34:05.140: WARN/System.err(25961):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2103)
11-17 14:34:05.140: WARN/System.err(25961):     at android.app.ActivityThread.access$1500(ActivityThread.java:122)
11-17 14:34:05.140: WARN/System.err(25961):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1078)
11-17 14:34:05.140: WARN/System.err(25961):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-17 14:34:05.140: WARN/System.err(25961):     at android.os.Looper.loop(Looper.java:132)
11-17 14:34:05.140: WARN/System.err(25961):     at android.app.ActivityThread.main(ActivityThread.java:4123)
11-17 14:34:05.140: WARN/System.err(25961):     at java.lang.reflect.Method.invokeNative(Native Method)
11-17 14:34:05.140: WARN/System.err(25961):     at java.lang.reflect.Method.invoke(Method.java:491)
11-17 14:34:05.140: WARN/System.err(25961):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
11-17 14:34:05.140: WARN/System.err(25961):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
11-17 14:34:05.140: WARN/System.err(25961):     at dalvik.system.NativeStart.main(Native Method)

What does this mean? 这是什么意思?

Now, if I don't create DatagramSocket and DatagramPacket cyclic any more, I get a different stack trace. 现在,如果我不再创建循环的DatagramSocket和DatagramPacket,则会得到不同的堆栈跟踪。 It is: 它是:

11-17 15:06:42.590: WARN/System.err(26812): android.os.NetworkOnMainThreadException
11-17 15:06:42.590: WARN/System.err(26812):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)
11-17 15:06:42.590: WARN/System.err(26812):     at dalvik.system.BlockGuard$WrappedNetworkSystem.recv(BlockGuard.java:332)
11-17 15:06:42.590: WARN/System.err(26812):     at org.apache.harmony.luni.net.PlainDatagramSocketImpl.doRecv(PlainDatagramSocketImpl.java:165)
11-17 15:06:42.590: WARN/System.err(26812):     at org.apache.harmony.luni.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:174)
11-17 15:06:42.590: WARN/System.err(26812):     at java.net.DatagramSocket.receive(DatagramSocket.java:391)
11-17 15:06:42.590: WARN/System.err(26812):     at com.example.MyService.onCreate(MyService.java:114)
11-17 15:06:42.610: WARN/System.err(26812):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2103)
11-17 15:06:42.610: WARN/System.err(26812):     at android.app.ActivityThread.access$1500(ActivityThread.java:122)
11-17 15:06:42.610: WARN/System.err(26812):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1078)
11-17 15:06:42.610: WARN/System.err(26812):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-17 15:06:42.610: WARN/System.err(26812):     at android.os.Looper.loop(Looper.java:132)
11-17 15:06:42.610: WARN/System.err(26812):     at android.app.ActivityThread.main(ActivityThread.java:4123)
11-17 15:06:42.610: WARN/System.err(26812):     at java.lang.reflect.Method.invokeNative(Native Method)

Has anyone an idea why I can't receive UDP packets? 有谁知道为什么我不能接收UDP数据包?

A couple of things: 有两件事:

Since you reuse the same port, you might need to create a socket, call setReuseAddress(true) , and then bind the socket to the port. 由于您重复使用了同一端口,因此可能需要创建一个套接字,调用setReuseAddress(true) ,然后将套接字绑定到该端口。

InterruptedIOException is a subclass of IOException, setSOTimeout(1000); InterruptedIOException是IOException的子类setSOTimeout(1000); will only wait (block) for 1 second before throwing this exception 在抛出此异常之前只会等待(阻止)1秒

UPDATED: The exceptions show the problems: 更新:异常显示了问题:

java.net.BindException: Address already in use

Which I believe will be fixed by using the setReuseAddress (above)? 我相信通过使用setReuseAddress(上面)可以解决哪些问题?

and

android.os.NetworkOnMainThreadException

Which means you're running this code on a the main UI thread, which will block the responiveness of the UI and possibly cause an ANR (probably not if you keep setSOTimeout(1000), but anyway...). 这意味着您正在主UI线程上运行此代码,这将阻止UI的响应性并可能导致ANR(如果保留setSOTimeout(1000),可能不是,但无论如何...)。 3.0 and later doesn't allow network requests on the UI thread so you need to put it into an AsyncTask (or Thread). 3.0及更高版本不允许在UI线程上进行网络请求,因此您需要将其放入AsyncTask (或Thread)中。

You may have networking issues if you are trying this on emulator. 如果您在模拟器上尝试此操作,则可能会遇到网络问题。 Emulator is a virtual machine which is connected directly to your router device. 仿真器是直接连接到路由器设备的虚拟机。 Your emulator cannot reach your local device, or any other devices on the local network. 仿真器无法访问本地设备或本地网络上的任何其他设备。

So that, if you wait answer from your local machine, or another machine on the lan, you may need portforwarding . 因此,如果您等待本地计算机或局域网中其他计算机的答复,则可能需要portforwarding

First try your application on a real device to decide if it is an emulator problem or not, than try other solutions. 首先,在其他设备上尝试在真实设备上确定应用程序是否是模拟器问题,然后再尝试其他解决方案。

I used UDP Broadcast on 3.2 once and it worked 我曾经在3.2上使用过UDP广播,它可以正常工作

Simplified Code of mine: 我的简化代码:

DatagramSocket socket;
socket = new DatagramSocket(aport);
socket.setBroadcast(true);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);

This worked for me. 这对我有用。 If you use broadcasts try setBroadcast(true). 如果使用广播,请尝试使用setBroadcast(true)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM