Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DatagramChannel在Android上未接收任何字节_Java_Android_Networking_Udp_Selector - Fatal编程技术网

Java DatagramChannel在Android上未接收任何字节

Java DatagramChannel在Android上未接收任何字节,java,android,networking,udp,selector,Java,Android,Networking,Udp,Selector,更新 我尝试了相同的实现,但这次使用了ServerSocketChannel/SocketChannel。这在安卓系统上有效。看起来我在安卓上的UDP上有100%的数据包丢失。有人对这件事的原因有想法吗?(这不是WiFi问题。UDP客户端在我的笔记本上工作。) 原创 我在Android应用程序中接收数据包时遇到问题。Android应用程序能够向桌面服务器发送数据,桌面服务器立即回复,但始终接收零字节。当我将其用作桌面客户端应用程序时,同样的代码也可以工作 我的Android应用程序具有互联网权限

更新
我尝试了相同的实现,但这次使用了ServerSocketChannel/SocketChannel。这在安卓系统上有效。看起来我在安卓上的UDP上有100%的数据包丢失。有人对这件事的原因有想法吗?(这不是WiFi问题。UDP客户端在我的笔记本上工作。)

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

我的Android应用程序具有互联网权限。我还尝试了网络,改变无线多播状态,接入无线状态和接入网络状态。可悲的是,这没有什么区别

在设备和模拟器上都进行了尝试

下面是代码和输出示例

主要活动:

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);
}
}
公共类客户端实现可运行{
私有静态最终字符串LOG_TAG=“NET”;
私有静态最终字符串IP=“-->”;
专用静态最终int端口=6543;
私有最终ByteBuffer ByteBuffer=ByteBuffer.allocate(256);
私有布尔运行;
公共客户机(){
运行=错误;
}
@凌驾
公开募捐{
试一试{
最终选择器=Selector.open();
final DatagramChannel DatagramChannel=DatagramChannel.open();
datagramChannel.configureBlocking(假);
datagramChannel.register(选择器、SelectionKey.OP_写入);
连接(新的InetSocketAddress(IP,端口));
运行=真;
(跑步时){
selector.select();
final Iterator keys=selector.selectedKeys().Iterator();
while(keys.hasNext()){
最终选择键=键。下一步();
if(key.isReadable()){
把手(钥匙);
}
if(key.isValid()&&key.isWritable()){
handleWrite(键);
}
键。移除();
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
private void HandlerRead(最终选择密钥密钥)引发IOException{
final DatagramChannel=(DatagramChannel)key.channel();
byteBuffer.clear();
最终SocketAddress from=通道.receive(byteBuffer);
byteBuffer.flip();
Log.i(Log_标记,String.format(“从%s接收%d字节”,byteBuffer.limit(),from));
key.interesttops(选择key.OP_WRITE);
}
private void handleWrite(最终选择密钥)引发IOException{
final DatagramChannel=(DatagramChannel)key.channel();
byteBuffer.clear();
byteBuffer.putInt(1234);
byteBuffer.flip();
最终SocketAddress to=新的InetSocketAddress(IP,端口);
final int bytes=channel.send(byteBuffer,to);
Log.i(Log_标记,String.format(“发送%d字节到%s”,字节到));
key.interesttops(选择key.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();
}
}
公共类服务器实现可运行{
专用静态最终int端口=6543;
私有最终ByteBuffer ByteBuffer=ByteBuffer.allocate(256);
来自的私有SocketAddress;
私有布尔运行;
公共服务器(){
from=null;
运行=错误;
}
@凌驾
公开募捐{
试一试{
最终选择器=Selector.open();
final DatagramChannel DatagramChannel=DatagramChannel.open();
datagramChannel.configureBlocking(假);
datagramChannel.socket().setReuseAddress(true);
datagramChannel.register(选择器,SelectionKey.OP_READ);
bind(新的InetSocketAddress(端口));
运行=真;
(跑步时){
selector.selectNow();
final Iterator keys=selector.selectedKeys().Iterator();
while(keys.hasNext()){
最终选择键=键。下一步();
if(key.isReadable()){
把手(钥匙);
}
if(key.isValid()&&key.isWritable()){
handleWrite(键);
}
键。移除();
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
private void HandlerRead(最终选择密钥密钥)引发IOException{
final DatagramChannel=(DatagramChannel)key.channel();
byteBuffer.clear();
from=信道接收(byteBuffer);
byteBuffer.flip();
System.out.println(String.format(“从%s接收%d字节”,byteBuffer.limit(),from));
key.interesttops(选择key.OP_WRITE);
}
private void handleWrite(最终选择密钥)引发IOException{
final DatagramChannel=(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(“发送%d字节到%s”,字节,从));
}
key.interesttops(选择key.OP_READ);
}
公共静态void main(字符串参数[]){
新线程(新服务器()).start();
}
}
客户端输出:

将4个字节发送到/——:6543
从null接收到0字节
将4个字节发送到/——:6543
从null接收到0字节

服务器输出:

从/-:52974接收到4个字节
将4个字节发送到/——:52974
从/-:52974接收到4个字节
将4个字节发送到/——:52974


当您不调用bind()时,为什么要在客户端中调用setReuseAddress()?你为什么睡觉?为什么要调用connect()并在send()中指定目标地址?当相应的参数是整数时,为什么要指定%s?@EJP在从服务器代码复制演示代码后没有删除它。只是睡觉,这样我就不会被淹死