简体   繁体   English

在 Android 中的 BluetoothSocket inputstream.read() 中实现超时

[英]Implement a timeout in BluetoothSocket inputstream.read() in Android

Is it possible to implement a timeout in an inputstream.read() function from a BluetoothSocket in Android?是否可以在 Android 中的 BluetoothSocket 的 inputstream.read() 函数中实现超时?

I've tried using Thread.sleep() but this only pauses my activity.我试过使用 Thread.sleep() 但这只会暂停我的活动。

---Update--- - -更新 - -

I had an idea, make 2 thread code herereads(t1 & t2) where each thread interrupt other, one of them(t1) do a sleep(5000) then interrupt the other thread(t2), from the other side the other thread(t2) if in read the inputstream detects some character as 0x0D interrupt the other thread(t1), but here is my question, does anybody can help me?我有一个想法,在此处创建 2 个线程代码(t1 和 t2),其中每个线程中断另一个线程,其中一个(t1)执行 sleep(5000)然后中断另一个线程(t2),从另一侧另一个线程( t2)如果在读取输入流检测到一些字符为 0x0D 中断另一个线程(t1),但这是我的问题,有人可以帮助我吗? because i didn't use interrupt() method of threads, I hope someone can help me, thank you...因为我没有使用线程的interrupt()方法,希望有人能帮帮我,谢谢...

---Update--- - -更新 - -



        public void run(){
        while(true){
            try {
            char r;
            String respuesta = "";
            while (true) {
                    r = (char) mmInStream.read();
                respuesta += r;
                if (r == 0x3e) {
                break;
                    }
                }
            respuesta = respuesta.replaceAll(" ", "");
            Log.d("respuesta", respuesta);
            rHandler.obtainMessage(MESSAGE_READ, -1, -1, respuesta).sendToTarget();
            } catch (IOException readException) {
            Log.e("ServicioGeneral", "Error de lectura", readException);
            this.interrupt();
            connectionLost();
            // posibly break();
            }
        }
    }

This is my implementation when something comes in a different Thread, the problem is that the timeout will be reached if i dont get the 0x3e character from de mmInStream.这是我在不同线程中出现某些内容时的实现,问题是如果我没有从 de mmInStream 中获取 0x3e 字符,则会达到超时。

I supposed that in the second example i must use a notifyAll(), but, when do I have to start the readThread()?我想在第二个例子中我必须使用notifyAll(),但是,我什么时候必须启动readThread()?

Thank you, @weeman谢谢你,@weeman

You could do something like this:你可以这样做:

InputStream in = someBluetoothSocket.getInputStream();
int timeout = 0;
int maxTimeout = 8; // leads to a timeout of 2 seconds
int available = 0;

while((available = in.available()) == 0 && timeout < maxTimeout) {
    timeout++;
    // throws interrupted exception
    Thread.sleep(250);
}

byte[] read = new byte[available];
in.read(read);

This way you are able to initially read from a stream with a specific timeout.通过这种方式,您可以最初从具有特定超时的流中读取。 If u want to implement a timeout at any time of reading you can try something like this:如果你想在阅读的任何时间实现超时,你可以尝试这样的事情:

Thread readThread = new ReadThread(); // being a thread you use to read from an InputStream
try {
   synchronized (readThread) {
      // edit: start readThread here
      readThread.start();
      readThread.wait(timeOutInMilliSeconds);
   }
catch (InterruptedException e) {}

using this you may need some kind of event handler to notify your application if the thread actually read something from the input stream.使用它您可能需要某种事件处理程序来通知您的应用程序,如果线程实际上从输入流中读取了某些内容。

I hope that helps!我希望这有帮助!

----edit: - - 编辑:

I implemented an example without using any handlers.我在不使用任何处理程序的情况下实现了一个示例。

Socket s = new Socket("localhost", 8080);
    final InputStream in = s.getInputStream();

    Thread readThread = new Thread(new Runnable() {
        public void run() {
            int read = 0;
            try {
                while((read = in.read()) >= 0) {
                    System.out.println(new String(new byte[]{ (byte) read }));
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });

    synchronized (readThread) {
        readThread.start();
        try {
            readThread.wait(2000);

            if(readThread.isAlive()) {
                                    // probably really not good practice!
                in.close();
                System.out.println("Timeout exceeded!");
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

A Kotlin extension function for socket read with timeout:用于超时读取套接字的 Kotlin 扩展函数:

fun InputStream.read(
  buffer: ByteArray,
  offset: Int,
  length: Int,
  timeout: Long
): Int = runBlocking {
    val readAsync = async {
        if (available() > 0) read(buffer, offset, length) else 0
    }
    var byteCount = 0
    var retries = 3
    while (byteCount == 0 && retries > 0) {
        withTimeout(timeout) {
            byteCount = readAsync.await()
        }
        delay(timeout)
        retries--
    }
    byteCount
}

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

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