0

I use some of the Bluetooth chat samplecode for sending a SMALL (177 byte to 3617 byte) "settings-file" "securly" between apps. when it is under 1024 bit everything works fine: (so the 177 works PERFECT) sendingdevice press "send button" and the reciver gets it (with a dialog if they want it..) (and I save the "string" to a "settings"file on that device)

but if the file is over 1024 it gets chunkt/cut off.. (example: 2000byte) so the file gets corrupted (data-loss but some info remains..)

Probably I need to "split" my file in 1024 bits and send the bits and in the receiver-end, I need to "add them all up"..

but I don't know the "standard best practices" for this, do you have any suggestions?

I have tryed to "only higher" the 1024 byte to 65536byte, but that don't work.. (or maby I do this wrong..)

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;
            }
        }
    }

sedan write:

/**
     * 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);
        }
    }

and when i "click on send settings":

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

and in "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);
    }

and:

    /**
 * 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);
}

but I think you know what Im lookning for ... (or can I some how change the "BluetoothChat" so it can sent and recive a large Sring, and not "byte:s"? :-) )

Best REGARDS to you all :-)

EDIT: on the reader side I have this:

on the "reader end" I have: ....

     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;

Here is the splitting-chunk-problem now.. if i send under ~ 1024 I receive the correct amount of settings ant i can save this fine :-)

If i sent larger then 1024 I get first for exampel "6 settings from.." and then a new message that I recived "1 settings from.." message :-(

just for your info:

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();
        }


    }

so i think it is: case MESSAGE_READ: is not only called if a complete file is received, it is also called if a small chunks is received. So I probably should place the "readFile-chunk" in a separate buffer (i.e. mNewBufForFile += readFileChunk) And then check the mNewBufForFile has a complete packet in it (how?). If it is done: I "save" the file message and then clear all buffer.

but how can i "split this from "Message_read", and do I "add a stopping bit" so i can check when i recive all the data? or can i do this better?

  • `SMALL (177 byte to 3617 byte) ` ? You mean `SMALL (177 byte to 1024 byte) ` – greenapps Mar 26 '15 at 13:49
  • `String message` ? What are you doing with that? – greenapps Mar 26 '15 at 13:51
  • `sendMessage(settingInAString);`. Please tell how many bytes you are going to send. Tell also how many chucks of how many bytes each you receive. – greenapps Mar 26 '15 at 13:52
  • Small: I have settinsfile that is from 177 to 3617 byte and I can send a 177-file OK , but not a 2000 ant not a 3000 file :-( – user3245324 Mar 27 '15 at 09:04
  • `Small: I have settinsfile that is from 177 to 3617 `. That is not the only thing i asked. I asked also how big the chuncks were that came in. – greenapps Mar 27 '15 at 09:48

1 Answers1

1

You can send as many bytes as you want. They come in in chunks smaller than the size of buffer (1024). Indeed the original code will mix all up caused by using one buffer. Change

  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();

to

    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();

The data still comes in in chuncks but now you get all displayed in the rigth sequence.

As the chunck sizes -during some tests- are smaller than 1024 it makes no sense to have a bigger buffer. If you want to transfer a real file you should concatenate all together. This is a normal action using sockets.

greenapps
  • 11,154
  • 2
  • 16
  • 19
  • Interesting!, do you have any ideas how can I "add the chunks" to a file? ´code – user3245324 Mar 27 '15 at 08:18
  • You are supposed to first react on my code. Does this work for you too in the way i described? – greenapps Mar 27 '15 at 08:21
  • Hi sorry the "5min edit" had passed when I edit this one.... I had edit the whileloop, And it looks like its working, but as you told my : the chunk:s is still "chunks".. please see my edited info in question.... – user3245324 Mar 27 '15 at 08:30
  • You added a lot of irrelevant code. If you want to add the chuncks together you have to do it in the loop I posted. Before you call obtainMessage(). NOT in obtainMessage(). – greenapps Mar 27 '15 at 09:36
  • The stopbit idea is ok but you will not do with one bit of course. You would need several bytes to mark the end of a file. A sequence of bytes that would never happen in a real file. Sending only plain text file you could easily define such a sequence of bytes. Better would work to send in an integer ( four bytes) the size of the file first. Then you can declare a big enough buffer to collect all chuncks. And you can send all kind of files like images too. – greenapps Mar 27 '15 at 10:09