【问题标题】:1024 buffer in Bluetooth chat chunks my information ;-(蓝牙聊天中的 1024 缓冲区块我的信息;-(
【发布时间】:2015-05-30 11:57:07
【问题描述】:

我使用一些蓝牙聊天示例代码在应用程序之间“安全地”发送 SMALL(177 字节到 3617 字节)“设置文件”。 当它低于 1024 位时,一切正常:(所以 177 工作完美) 发送设备按下“发送按钮”,接收方得到它(如果他们想要的话,会有一个对话框......)(我将“字符串”保存到该设备上的“设置”文件中)

但如果文件超过 1024,它会被截断/截断..(例如:2000byte) 所以文件被损坏(数据丢失,但一些信息仍然存在..)

可能我需要将我的文件“拆分”为 1024 位并发送这些位,而在接收端,我需要“将它们全部加起来”..

但我不知道这方面的“标准最佳实践”,您有什么建议吗?

我尝试将 1024 字节“仅更高”到 65536 字节,但这不起作用.. (或者可能我做错了..)

public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];
        int bytes;
        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                // Start the service over to restart listening mode
                BluetoothChatService.this.start();
                break;
            }
        }
    }

轿车写:

/**
     * Write to the connected OutStream.
     * @param buffer  The bytes to write
     */
    public void write(byte[] buffer) {
        try {
            mmOutStream.write(buffer);
            mmOutStream.flush();

            // Share the sent message back to the UI Activity
            mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
                    .sendToTarget();
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
        }
    }

当我“点击发送设置”时:

String message = view.getText().toString();
            String settingInAString = getSettingInALargeString();
            sendMessage(settingInAString);

在“sendMessage”中:

if (message.length() > 0) {
        // Get the message bytes and tell the BluetoothChatService to write
        byte[] send = message.getBytes();
        mChatService.write(send); //SO convert to byte and then send the byte..

        // Reset out string buffer to zero and clear the edit text field
        mOutStringBuffer.setLength(0);
        mOutEditText.setText(mOutStringBuffer);
    }

和:

    /**
 * Write to the ConnectedThread in an unsynchronized manner
 * @param out The bytes to write
 * @see ConnectedThread#write(byte[])
 */
public void write(byte[] out) {
    // Create temporary object
    ConnectedThread r;
    // Synchronize a copy of the ConnectedThread
    synchronized (this) {
        if (mState != STATE_CONNECTED) return;
        r = mConnectedThread;
    }
    // Perform the write unsynchronized
    r.write(out);
}

但我想你知道我在寻找什么...... (或者我可以更改“BluetoothChat”以便它可以发送和接收一个大的 Sring,而不是“byte:s”吗?:-))

向大家致以最诚挚的问候 :-)

编辑: 在读者方面,我有这个:

在“阅读器端”我有: ....

     case MESSAGE_READ:
    byte[] readBuf = (byte[]) msg.obj;
//only a byte redebuffer, hmm can I change this? or do i use a whileloop?
    // construct a string from the valid bytes in the buffer
    String readMessage = new String(readBuf, 0, msg.arg1);
    recivedStringCheckFirst(readMessage); 
//simple-check if the data is a "data-setting-file"
    String [] allSettingsInALargeArray1 = doSplitOnLargeString(readMessage);
    int titleArrayLength1 = getLengthOffTheUpCommingTitleArrayFromNew(allSettingsInALargeArray1); //this do a split and looks if it is 1,2,3..20 settings..) 
    mConversationArrayAdapter.add(titleArrayLength1 + " datasettings recived from " + mConnectedDeviceName + " SAVE THIS?"); 
//this type this text to the "chatwindow"               
                    break;

现在是拆分块问题.. 如果我在 ~ 1024 下发送,我会收到正确数量的设置,我可以保存这个很好:-)

如果我发送的数据大于 1024,我首先会收到例如“来自.. 的 6 个设置”,然后是收到“来自.. 的 1 个设置”的新消息:-(

仅供参考:

protected void recivedStringCheckFirst(String readMessage) {
        String eventuellSettings = readMessage;

        if (isThisASettingFile(eventuellSettings)){
            //of ok..
            System.out.println("incommingISAsetting :-) ");

            inkommenSettings = eventuellSettings;
            showDialog(); //dialog for save settings?
        }
        if (!isThisASettingFile(eventuellSettings)){
            //not a settingsfile! 
            Toast.makeText(this, "try again..", Toast.LENGTH_LONG).show();
        }


    }

所以我认为是: 案例 MESSAGE_READ: 不仅在收到完整文件时调用, 如果收到小块,它也会被调用。 所以我可能应该将“readFile-chunk”放在一个单独的缓冲区中 (即 mNewBufForFile += readFileChunk) 然后检查 mNewBufForFile 中有一个完整的数据包(如何?)。如果完成:我“保存”文件消息,然后清除所有缓冲区。

但是我如何“从“Message_read”中“拆分”,我是否可以“添加一个停止位”以便检查何时收到所有数据?或者我可以做得更好吗?

【问题讨论】:

  • SMALL (177 byte to 3617 byte) ?你的意思是SMALL (177 byte to 1024 byte)
  • String message ?你拿它做什么?
  • sendMessage(settingInAString);。请告诉您要发送多少字节。告诉你每个收到多少字节的卡盘。
  • Small:我有 177 到 3617 字节的 settinsfile,我可以发送 177 文件 OK ,但不是 2000 ant 不是 3000 文件 :-(
  • Small: I have settinsfile that is from 177 to 3617 。这不是我问的唯一问题。我还问进来的大块有多大。

标签: android bluetooth chat sendfile


【解决方案1】:

您可以发送任意数量的字节。它们以小于缓冲区大小(1024)的块形式出现。事实上,由于使用一个缓冲区,原始代码会混淆起来。改变

  byte[] buffer = new byte[1024];
    int bytes;
    // Keep listening to the InputStream while connected
    while (true) {
        try {
            // Read from the InputStream
            bytes = mmInStream.read(buffer);

            // Send the obtained bytes to the UI Activity
            mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                    .sendToTarget();

    while (true) {
            try {
                byte[] buffer = new byte[1024];
                // Read from the InputStream
                int nbytes = mmInStream.read(buffer);

                Log.i(TAG, "read nbytes: " + nbytes);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, nbytes, -1, buffer)
                        .sendToTarget();

数据仍然以大块的形式出现,但现在您将全部显示在正确的序列中。

由于块大小 - 在某些测试期间 - 小于 1024,因此拥有更大的缓冲区是没有意义的。如果要传输真实文件,则应将所有文件连接在一起。这是使用套接字的正常操作。

【讨论】:

  • 有趣!,您有什么想法可以“添加块”到文件中吗? '代码
  • 你应该首先对我的代码做出反应。像我描述的那样,这对你也有用吗?
  • 嗨,对不起,当我编辑这个时,“5分钟编辑”已经过去了……我编辑了 whileloop,它看起来像它的工作,但正如你告诉我的:块:s仍然是“块”..请查看我编辑的有问题的信息....
  • 你添加了很多不相关的代码。如果你想将块添加在一起,你必须在我发布的循环中进行。在调用 gainMessage() 之前。不在 gainMessage() 中。
  • stopbit 的想法是可以的,但你当然不会用一点。您将需要几个字节来标记文件的结尾。在真实文件中永远不会发生的字节序列。只发送纯文本文件,您可以轻松定义这样的字节序列。最好先发送文件大小的整数(四个字节)。然后你可以声明一个足够大的缓冲区来收集所有的块。你也可以发送各种文件,比如图片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
  • 2013-08-10
  • 2020-11-10
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
相关资源
最近更新 更多