0

I have a problem with my TCP connection. I send data (a simple string) via a smartphone to a tablet by a TCP socket connection. The connection works fine and data is transmitted as expected. But when I do a loop and in every iteration dos.write() is fired only one packages arrive on the tablets data receiver. What am I doing wrong?

Here's the sending part of my connection. It iterates through the list and writes every data to the DataOutputStream.

for(int i = 0; i <= logList.length - 1; ++i){
    String backupPayload = invertLogStringToJson(logList[i]);

    dos = new DataOutputStream(s.getOutputStream());

    dos.writeUTF(backupPayload);
    dos.flush();
    dos.close();

On the tablet I receive the data via this code snippet:

@Override
public void run() {
    try {

        while(true){
            mySocket = ss.accept();
            dis = new DataInputStream(mySocket.getInputStream());
            message = dis.readUTF();

            handler.post(() -> {
                bufferIntentSendCode.putExtra("data", message);
                ctx.sendBroadcast(bufferIntentSendCode);
            });
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

As I said the connection works fine when I send only one data package. But if I want to send multiple packages inside the loop only the first package will arrive at the destination.

Can anyone help me? :)

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
baja
  • 53
  • 4

1 Answers1

1

Calling close() on a DataOutputStream closes its associated OutputStream, and closing a socket's OutputStream closes the socket. This is documented behavior.

But, that should be OK, because your receiver code is only expecting to receive 1 single string anyway. You are calling dis.readUTF() only one time per TCP connection.

If you want to send multiple strings in a single connection, DON'T call dos.close() on the sending side (at least until all of the strings have been sent), and DO call dis.readUTF() in a loop on the receiving end until all strings have been received.

dos = new DataOutputStream(s.getOutputStream());

for(int i = 0; i < logList.length; ++i){
    String backupPayload = invertLogStringToJson(logList[i]);
    dos.writeUTF(backupPayload);
}
dos.flush();

dos.close();
@Override
public void run() {
    try {
        while (true) {
            mySocket = ss.accept();
            dis = new DataInputStream(mySocket.getInputStream());

            try {
                while (true) {
                    message = dis.readUTF();
                    handler.post(() -> {
                        bufferIntentSendCode.putExtra("data", message);
                        ctx.sendBroadcast(bufferIntentSendCode);
                    });
                }
            } catch (IOException e) {
            }

            dis.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Alternatively, send the list length before sending the actual strings, and then read the length before reading the strings:

dos = new DataOutputStream(s.getOutputStream());

// maybe other things first...

dos.writeInt(logList.length);
for(int i = 0; i < logList.length; ++i){
    String backupPayload = invertLogStringToJson(logList[i]);
    dos.writeUTF(backupPayload);
}
dos.flush();

// maybe other things next...

dos.close();
@Override
public void run() {
    try {
        while (true) {
            mySocket = ss.accept();
            dis = new DataInputStream(mySocket.getInputStream());

            try {
                // maybe other things first...

                int length = dis.readInt();
                for (int i = 0; i < length; ++i) {
                    message = dis.readUTF();
                    handler.post(() -> {
                        bufferIntentSendCode.putExtra("data", message);
                        ctx.sendBroadcast(bufferIntentSendCode);
                    });
                }

                // maybe other things next...

            } catch (IOException e) {
            }

            dis.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770