簡體   English   中英

在關閉Android BluetoothSocket之前如何確保已發送所有數據

[英]How to ensure all data is sent before closing Android BluetoothSocket

我正在制作一個可通過藍牙在手機之間進行通訊的android應用。 為了節省電池,我想避免一直保持藍牙連接打開。 因此,每次我要發送消息時,我都會打開一個連接,發送消息,刷新然后關閉。

我的問題是, 有時但並非總是如此,接收電話給我帶來了臭名昭著的“ java.io.IOException:bt套接字關閉,讀取返回:-1”。 我看到BluetoothSocket文檔指出

BluetoothSocket是線程安全的。 特別是,close()將始終立即中止正在進行的操作並關閉套接字。

但是,一般的藍牙頁面指出:

當您完成BluetoothSocket時,請始終調用close()。 這樣做將立即關閉連接的插座並釋放所有相關的內部資源。

這是我發送消息的線程的摘錄。

            localSocket = device.createRfcommSocketToServiceRecord(MY_UUIDS[0]);
            localSocket.connect();
            Log.d(TAG, "Correctly Connected on " + MY_UUIDS[0]);
            OutputStream rawOutputStream = localSocket.getOutputStream();
            ObjectOutputStream messageOutputStream = new ObjectOutputStream(rawOutputStream);
            // Actually send the message
            messageOutputStream.writeObject(message);
            messageOutputStream.flush();
            rawOutputStream.flush();

            messageOutputStream.close();
            rawOutputStream.close();
            localSocket.close();

這是我接受傳入連接的線程的摘錄:

                    InputStream rawInputStream = socket.getInputStream();
                    ObjectInputStream messageInputStream = new ObjectInputStream(rawInputStream);
                    BluetoothMessage joinMessage = (BluetoothMessage) messageInputStream.readObject();
                    BluetoothDevice device = socket.getRemoteDevice();
                    messageInputStream.close();
                    rawInputStream.close();
                    socket.close();
                    socket = null;

我意識到刷新和關閉是多余的,但事實是, 有時由於硬件延遲,套接字會在發送所有消息之前在發送端關閉。

我可以確認所有消息每次都能完美到達,無論我繼續發送它們有多快....如果我不關閉套接字。 但是,我知道關閉插座始終是最佳實踐。

那么,如何確保在調用socket.close()之前發送所有消息? 顯然,flush()和stream close()並沒有做應有的工作,否則,無論我何時調用socket.close(),消息都將被完全發送。

首先,我想說您的第一個假設並不完全正確。 如果兩個設備將持續通信,則實際上保持連接打開可能會更有效。

但是關於您的問題,的確是,有時候,拋出IOException時,輸入的字節可能沒有被完全讀取。

確保的唯一方法是在其中實現某種協議:

  1. 從一台設備寫入數據
  2. 從遠程設備讀取
  3. 從遠程設備回復某種“確認”,以確認您的數據已被完全讀取。
  4. 僅在收到“ ack”后才關閉插座。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM