【问题标题】:Knowing How to Detect a Disconnection when Reading Socket Data (InputStream)知道如何在读取套接字数据(InputStream)时检测断开连接
【发布时间】:2012-08-10 21:13:03
【问题描述】:

我有一个线程不断地从 InputStream 中读取数据。 InputStream 数据来自蓝牙套接字。以前,我没有在 InputStream 读取语句周围使用 if(mmInStream.available() > 0) 并且当蓝牙套接字消失(有人关闭设备)时, mmInStream.read 会抛出 IOException 然后我可以处理我的断开逻辑。确定何时发生断开连接的最佳方法是什么?

0xEE 的第一个字节告诉我它是数据包的领导者,第二个字节告诉我要读取的长度。

public void run() {
            byte[] tempBuffer = new byte[1024];
            byte[] buffer = null;
            int byteRead=0;
        long timeout=0;
        long wait=100;

            while (true) {
                try {
                timeout = System.currentTimeMillis() + wait;
                    if(mmInStream.available() > 0) {
                        while((mmInStream.available() > 0) && (tempBuffer[0] != (byte) 0xEE) && (System.currentTimeMillis() < timeout)){
                        byteRead = mmInStream.read(tempBuffer, 0, 1);
                    }
                    if(tempBuffer[0] == (byte) 0xEE){
                        timeout = System.currentTimeMillis() + wait; 
                        while(byteRead<2 && (System.currentTimeMillis() < timeout)){
                            byteRead += mmInStream.read(tempBuffer, 1, 1); 
                        }
                    }
                    timeout = System.currentTimeMillis() + wait; 
                    while((byteRead<tempBuffer[1]) && (System.currentTimeMillis() < timeout)){
                        byteRead += mmInStream.read(tempBuffer, byteRead, tempBuffer[1]-byteRead); 
                    }
                    }

                    if(byteRead > 0){
                        //do something with the bytes read in               
                    } 
                }

                catch (IOException e) {
                    bluetoothConnectionLost();
                    break;
                }
            }

        }

【问题讨论】:

    标签: java sockets stream network-programming


    【解决方案1】:

    您不需要使用 available() 进行所有这些恶意操作。只需使用 setSoTimeout 设置读取超时,读取,检测读取返回 -1,使用 read 返回的计数 if > 0 而不是假设缓冲区已满,捕获 SocketTimeoutException 以检测读取超时,并捕获 IOException 以检测其他损坏。

    【讨论】:

      【解决方案2】:

      看了下文档,我觉得是这样的:

      public void run() {
          byte[] tempBuffer = new byte[1024];
          int byteRead = 0;
      
          while (true) {
              try {
                  bytesRead = mmInStream.read(tempBuffer, 0, tempBuffer.length);
                  if (bytesRead < 0)
                      // End of stream.
                      break;
      
                  // Do something with the bytes read in. There are bytesRead bytes in tempBuffer.
              } catch (IOException e) {
                  bluetoothConnectionLost();
                  break;
              }
          }
      }
      

      【讨论】:

      • 这就是我之前获得代码的方式,但是使用这种方法我们遇到了数据丢失的情况。在 if(mmInStream.available() > 0) 检查中,我们检查第一个字节以确保它是数据包的领导者(否则忽略),然后第二个字节告诉我要读取的长度,所以我一直读到那个长度.我将更新我的代码以反映这一点,只是想保持简单
      • 您可以扫描tempBuffer 以获取前导字节。如果你找到它,下面的字节将是长度和数据。当然,如果不是全部,您可能还需要读取更多字节。
      【解决方案3】:

      我觉得是这样的:

       void fun(){
         isOpen = true;
         try{
            InputStream stream = socket.getInputStream();
            while(isOpen){
               byte[] buf = new byte[8];
               int pos = stream.read(buf);
               if (pos < 0) {
                  throw new IOException();
               }
               //dosomething...
            }
        }catch(IOException e) {
          isOpen  = false;
        }finally{
          //do dispose here
        }
      }
      

      【讨论】:

      • 请在您的回答中添加解释
      猜你喜欢
      • 2012-12-10
      • 2013-11-22
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      • 2013-04-19
      相关资源
      最近更新 更多