2016-06-28 84 views
0

在我正在開發的程序中,我有兩個設備通過藍牙相互通話。當應用程序第一次啓動時,兩個設備連接正常,但是當連接被切斷並重新初始化(即服務器線程被終止然後重新創建)時,儘管BluetoothServerSocket已經接受連接,但它仍然失敗。在服務器端,我有藍牙ServerSocket不接受

void handleConnection() throws Exception { 
    bss = BluetoothAdapter.getDefaultAdapter().listenUsingRfcommWithServiceRecord(Constants.BITMAP_NAME, 
         UUID.fromString(Constants.BITMAP_UUID)); 
    running.set(true); 
    Logger.logE("accepting"); 
    BluetoothSocket socket = bss.accept(); 
    Logger.logE("accepted"); 
    context.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      if (connectionCallback != null) 
       connectionCallback.onConnectionMade(); 
     } 
    }); 
    //handle connection in a loop... 
    try { 
     is.close(); 
     is = null; 
    } catch (IOException ignored) { 
     Logger.exception(ignored); 
    } 
    try { 
     socket.close(); 
     socket = null; 
    } catch (IOException ignored) { 
     Logger.exception(ignored); 
    } 
} 

而且在客戶端上我有

void handleConnection() throws Exception { 
    BluetoothSocket socket = connect. 
      createRfcommSocketToServiceRecord(UUID.fromString(Constants.BITMAP_UUID)); 
    Logger.logE("preparing to connect"); 
    socket.connect(); 
    Logger.logE("Connected"); 
    if (connectionCallback != null) { 
     context.runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       connectionCallback.onConnectionMade(); 
      } 
     }); 
     Logger.logE("callback fired"); 
    } 
    //Handle the connection... 
    Logger.logE("closing client"); 
    try { 
     os.close(); 
     os = null; 
    } catch (Exception ex) { 
     Logger.exception(ex); 
    } 
    try { 
     socket.close(); 
     socket = null; 
    } catch (Exception ex) { 
     Logger.exception(ex); 
    } 
} 

重新啓動服務器,並嘗試重新連接,客戶端超時與消息

java.io.IOException: read failed, socket might closed or timeout, read ret: -1 

後在socket.connect();行。在監視客戶端時,我在Logcat中看到消息preparing to connect,而在監視服務器時看到消息accepting,但它從未超出這一點。

+0

您能否詳細說明「何時連接被切斷並重新初始化」以及在哪個語句拋出錯誤(java.io.IOException:讀取失敗,套接字可能關閉或超時,讀取ret:-1)? – solosodium

+0

@solosodium爲你更新了它。 – sjyn

回答

1

客戶端代碼似乎很好。我認爲問題來自服務器。

如果你去到Android documentation藍牙,你會看到藍牙服務器的示例:

private class AcceptThread extends Thread { 
    private final BluetoothServerSocket mmServerSocket; 

    public AcceptThread() { 
     // Use a temporary object that is later assigned to mmServerSocket, 
     // because mmServerSocket is final 
     BluetoothServerSocket tmp = null; 
     try { 
      // MY_UUID is the app's UUID string, also used by the client code 
      tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); 
     } catch (IOException e) { } 
     mmServerSocket = tmp; 
    } 

    public void run() { 
     BluetoothSocket socket = null; 
     // Keep listening until exception occurs or a socket is returned 
     while (true) { 
      try { 
       socket = mmServerSocket.accept(); 
      } catch (IOException e) { 
       break; 
      } 
      // If a connection was accepted 
      if (socket != null) { 
       // Do work to manage the connection (in a separate thread) 
       manageConnectedSocket(socket); 
       mmServerSocket.close(); 
       break; 
      } 
     } 
    } 

    /** Will cancel the listening socket, and cause the thread to finish */ 
    public void cancel() { 
     try { 
      mmServerSocket.close(); 
     } catch (IOException e) { } 
    } 
} 

問題的關鍵是,你需要運行在一個線程的服務器,以保持所有傳入連接的軌道。因爲您需要傳入的插座進行通信。

當你完成通信時記住關閉SOCKET也很重要。沒有正確關閉的套接字可能會導致硬件連接懸停,而軟件層不知道,這也可能是您當前問題的原因(由於缺乏實際通信的代碼,這是不確定的)。有關更多信息,請參閱this

+0

你是100%的權利。我相信該插座沒有正確關閉,這與您所描述的確實有關。 – sjyn