DatagramChannel在Android上没有收到任何字节

时间:2015-07-10 09:34:02

标签: java android networking udp selector

更新
我尝试了相同的实现,但这次使用的是ServerSocketChannel / SocketChannel。这适用于Android。似乎我在Android上以某种方式在UDP上有100%的数据包丢失。有没有人对这个原因有所了解? (这不是WiFi问题.UDP客户端可以从我的笔记本电脑上运行。)

原始
我在Android应用程序中收到数据包时遇到问题。 Android应用程序能够将数据发送到桌面服务器,桌面服务器立即回复,但始终接收零字节。当我将它用作桌面客户端应用程序时,相同的代码可以正常工作。

我的Android应用程序具有INTERNET权限。我还尝试使用NETWORK,CHANGE_WIFI_MULTICAST_STATE,ACCESS_WIFI_STATE和ACCESS_NETWORK_STATE。遗憾的是,这没有任何区别。

在设备和模拟器中尝试过它。

以下是代码和输出样本。

MainActivity:

private Thread thread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    thread = new Thread(new Client());
    thread.start();
}

客户端:

public class Client implements Runnable {
private static final String LOG_TAG = "NET";
private static final String IP = "--.---.---.--";
private static final int PORT = 6543;

private final ByteBuffer byteBuffer = ByteBuffer.allocate(256);

private boolean running;

public Client() {
    running = false;
}

@Override
public void run() {
    try {
        final Selector selector = Selector.open();
        final DatagramChannel datagramChannel = DatagramChannel.open();
        datagramChannel.configureBlocking(false);
        datagramChannel.register(selector, SelectionKey.OP_WRITE);
        datagramChannel.connect(new InetSocketAddress(IP, PORT));

        running = true;
        while (running) {
            selector.select();

            final Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
            while (keys.hasNext()) {
                final SelectionKey key = keys.next();

                if (key.isReadable()) {
                    handleRead(key);
                }

                if (key.isValid() && key.isWritable()) {
                    handleWrite(key);
                }

                keys.remove();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void handleRead(final SelectionKey key) throws IOException {
    final DatagramChannel channel = (DatagramChannel) key.channel();

    byteBuffer.clear();
    final SocketAddress from = channel.receive(byteBuffer);
    byteBuffer.flip();

    Log.i(LOG_TAG, String.format("Received %d bytes from %s", byteBuffer.limit(), from));

    key.interestOps(SelectionKey.OP_WRITE);
}

private void handleWrite(final SelectionKey key) throws IOException {
    final DatagramChannel channel = (DatagramChannel) key.channel();

    byteBuffer.clear();
    byteBuffer.putInt(1234);
    byteBuffer.flip();

    final SocketAddress to = new InetSocketAddress(IP, PORT);
    final int bytes = channel.send(byteBuffer, to);

    Log.i(LOG_TAG, String.format("Send %d bytes to %s", bytes, to));

    key.interestOps(SelectionKey.OP_READ);
}
}

服务器:

public class Server implements Runnable {
private static final int PORT = 6543;

private final ByteBuffer byteBuffer = ByteBuffer.allocate(256);

private SocketAddress from;

private boolean running;

public Server() {
    from = null;
    running = false;
}

@Override
public void run() {
    try {
        final Selector selector = Selector.open();
        final DatagramChannel datagramChannel = DatagramChannel.open();
        datagramChannel.configureBlocking(false);
        datagramChannel.socket().setReuseAddress(true);
        datagramChannel.register(selector, SelectionKey.OP_READ);
        datagramChannel.bind(new InetSocketAddress(PORT));

        running = true;
        while (running) {
            selector.selectNow();

            final Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
            while (keys.hasNext()) {
                final SelectionKey key = keys.next();

                if (key.isReadable()) {
                    handleRead(key);
                }

                if (key.isValid() && key.isWritable()) {
                    handleWrite(key);
                }

                keys.remove();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void handleRead(final SelectionKey key) throws IOException {
    final DatagramChannel channel = (DatagramChannel) key.channel();

    byteBuffer.clear();
    from = channel.receive(byteBuffer);
    byteBuffer.flip();

    System.out.println(String.format("Received %d bytes from %s", byteBuffer.limit(), from));

    key.interestOps(SelectionKey.OP_WRITE);
}

private void handleWrite(final SelectionKey key) throws IOException {
    final DatagramChannel channel = (DatagramChannel) key.channel();

    if (from != null) {
        byteBuffer.clear();
        byteBuffer.putInt(1234);
        byteBuffer.flip();

        final int bytes = channel.send(byteBuffer, from);

        System.out.println(String.format("Send %d bytes to %s", bytes, from));
    }

    key.interestOps(SelectionKey.OP_READ);
}

public static void main(String args[]) {
    new Thread(new Server()).start();
}
}

客户端输出:

  

将4个字节发送到/--.---.---.--:6543
  从null中收到0个字节   发送4个字节到/--.---.---.--:6543
  从null

收到0个字节

服务器输出:

  

从/--.---.---.--:52974收到4个字节   发送4个字节到/--.---.--- .--:52974
  收到了来自/--.---.---.--:52974的4个字节   发送4个字节到/--.---.---.--:52974

0 个答案:

没有答案