Android RFCOMM重传的问题

最后发布: 2015-12-08 16:22:52


问题

I am working with Android's RFCOMM Tutorial . 我正在使用Android的RFCOMM教程 I have it working, but I'm having an issue when I send large messages (this is intentional, and cannot be changed). 我可以使用它,但是在发送大消息时遇到问题(这是有意的,无法更改)。

The issue is that I will see the same data transferred multiple times, but it stops after sending X bytes, even though N of those bytes were duplicates. 问题是我将看到相同的数据多次传输,但是即使发送了N个字节,它们也会在发送X个字节后停止。

As an example, sending a chunk of 12800 bytes, my receiving side sees this data (cut down from the full log -- the numbers indicate the length of the string): 例如,发送12800字节的数据块,我的接收端看到了此数据(从完整的日志中删掉了-数字表示字符串的长度):

Reading: (990)yJv;ZU>h8JCfAEttQEA7V9BSkITgDn5350SdahFILcbwrYAfD7b_Oavhqr:DF 阅读:(990)yJv; ZU> h8JCfAEttQEA7V9BSkITgDn5350SdahFILcbwrYAfD7b_Oavhqr:DF
Reading: (2970)HQTZWMFv08G3qHiHn@4_f8KWrQX9v]gmV=tvqGFpP:c8yV^a0i17:ndDiOS 阅读:(2970)HQTZWMFv08G3qHiHn @ 4_f8KWrQX9v] gmV = tvqGFpP:c8yV ^ a0i17:ndDiOS
Reading: (990)ZdXZvCxK5sdLlKDnPrrP;2nuEItZ9<\\29e7x7lNFafHU]R@Ap=lBF\\M?1\\W_O 阅读:(990)ZdXZvCxK5sdLlKDnPrrP; 2nuEItZ9 <\\ 29e7x7lNFafHU] R @ Ap = lBF \\ M?1 \\ W_O
Reading: (990)ZdXZvCxK5sdLlKDnPrrP;2nuEItZ9<\\29e7x7lNFafHU]R@Ap=lBF\\M?1\\W_O 阅读:(990)ZdXZvCxK5sdLlKDnPrrP; 2nuEItZ9 <\\ 29e7x7lNFafHU] R @ Ap = lBF \\ M?1 \\ W_O
Reading: (990)ZdXZvCxK5sdLlKDnPrrP;2nuEItZ9<\\29e7x7lNFafHU]R@Ap=lBF\\M?1\\W_O 阅读:(990)ZdXZvCxK5sdLlKDnPrrP; 2nuEItZ9 <\\ 29e7x7lNFafHU] R @ Ap = lBF \\ M?1 \\ W_O
Reading: (1980)ZdXZvCxK5sdLlKDnPrrP;2nuEItZ9<\\29e7x7lNFafHU]R@Ap=lBF\\M?1\\W_ 阅读:(1980)ZdXZvCxK5sdLlKDnPrrP; 2nuEItZ9 <\\ 29e7x7lNFafHU] R @ Ap = lBF \\ M?1 \\ W_
Reading: (990)TD?lyEvS;[PMj>xpg5RiAIK8di61QNngkOvpoMhl=0`I@32iUuScR1xiGiZ: 阅读:(990)TD?lyEvS; [PMj> xpg5RiAIK8di61QNngkOvpoMhl = 0`I @ 32iUuScR1xiGiZ:
Reading: (990)Ahyxc2PMA?sub8l^:prr=D5vIaGw73@rS0EHTeT;XLcsq9k6li;MVw_IJ4QiSs 阅读:(990)Ahyxc2PMA?sub8l ^:prr = D5vIaGw73 @ rS0EHTeT; XLcsq9k6li; MVw_IJ4QiSs
Reading: (990)YQe:OWv_Iv_6eL@Yu>KUnbjmsN9KsidM1Vx6:LSsgZ[sbG3V>0dp7kkvUhX1^n 阅读:(990)YQe:OWv_Iv_6eL @ Yu> KUnbjmsN9KsidM1Vx6:LSsgZ [sbG3V> 0dp7kkvUhX1 ^ n
Reading: (920)YQe:OWv_Iv_6eL@Yu>KUnbjmsN9KsidM1Vx6:LSsgZ[sbG3V>0dp7kkvUhX1^n 阅读:(920)YQe:OWv_Iv_6eL @ Yu> KUnbjmsN9KsidM1Vx6:LSsgZ [sbG3V> 0dp7kkvUhX1 ^ n

As you can see, there are 3 exact retransmissions, and one retransmission that had more data appended. 如您所见,存在3次确切的重传,其中1次重传附加了更多数据。 However, the sum of all the lengths is 12800 -- the original size of the message. 但是,所有长度的总和为12800,即邮件的原始大小。

In case you're wondering, presently the data is just a random string. 如果您想知道,目前数据只是一个随机字符串。 So, no, it's not getting the same bits of data in there more than once. 因此,不,它不会多次获得相同的数据。 And I have confirmed this by looking at the sending side. 通过查看发送方,我已经确认了这一点。

Now, I need the data to come through without any corruption, so I'm checking a hash on the other side. 现在,我需要数据通过而没有任何损坏,因此我正在另一端检查哈希。 However, with the retransmissions, and the lost data, it isn't matching most of the time. 但是,由于重传和数据丢失,大多数时候它都不匹配。 And cutting out the retransmissions just leaves me with missing data. 取消重传只会使我丢失数据。

So, the issue seems to be two-fold: 因此,问题似乎有两个:

  1. Retransmissions are happening even though the data is received successfully. 即使成功接收到数据,重传仍在发生。
  2. Even when I'm smart about ignoring the retransmissions, all the data doesn't come through. 即使我很聪明地忽略了重传,所有数据也不会通过。 If N bytes are retransmitted, I'm left with N bytes of missing data. 如果重新传输了N个字节,我将剩下N个字节的丢失数据。

All relevant code for this has come directly from Android's website (link above). 所有与此相关的代码直接来自Android网站(上面的链接)。 Key points of interest however are: 但是,关键的兴趣点是:

Managing A Connection 管理连接

And this block, which comes from the full code from the tutorial I linked to: 这个块来自我链接到的教程的完整代码

private final Handler mHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
         switch (msg.what) { 
         case MESSAGE_STATE_CHANGE: 
             if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); 
             switch (msg.arg1) { 
             case BluetoothChatService.STATE_CONNECTED: 
                 mTitle.setText(R.string.title_connected_to); 
                 mTitle.append(mConnectedDeviceName); 
                 mConversationArrayAdapter.clear(); 
                 break; 
             case BluetoothChatService.STATE_CONNECTING: 
                 mTitle.setText(R.string.title_connecting); 
                 break; 
             case BluetoothChatService.STATE_LISTEN: 
             case BluetoothChatService.STATE_NONE: 
                 mTitle.setText(R.string.title_not_connected); 
                 break; 
             } 
             break; 
         case MESSAGE_WRITE: 
             byte[] writeBuf = (byte[]) msg.obj; 
             // construct a string from the buffer 
             String writeMessage = new String(writeBuf); 
             mConversationArrayAdapter.add("Me:  " + writeMessage); 
             break; 
         case MESSAGE_READ: 
             byte[] readBuf = (byte[]) msg.obj; 
             // construct a string from the valid bytes in the buffer 
             String readMessage = new String(readBuf, 0, msg.arg1); 
             mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage); 
             break; 
         case MESSAGE_DEVICE_NAME: 
             // save the connected device's name 
             mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); 
             Toast.makeText(getApplicationContext(), "Connected to " 
                            + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); 
             break; 
         case MESSAGE_TOAST: 
             Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), 
                            Toast.LENGTH_SHORT).show(); 
             break; 
         } 
     } 
 };
android bluetooth rfcomm