Search code examples
javaandroidsocketsdatainputstream

DataInputStream readInt() works only once


I'm using Java sockets to make two android devices communicating with the same app. The communication protocol is:

1. client sends packet size S
2. client sends byte array with size S

I'm using DataOutputStream and writeInt() to write the size as raw value on the stream. The server then reads this value whit DataInputStream and readInt(). The problem is that readInt() reads the right value only for the first packet. The second time this method returns a random int.

Relevant code snippets:

Client side: this method is called on top of a working TCP connection with the server

public void write(byte[] packet)
{
    try
    {
        dataOutputStream.writeInt(packet.length);
        dataOutputStream.flush();

        dataOutputStream.write(packet);
        dataOutputStream.flush();        
    }
    catch (IOException e)
    {
        Log.e(ERROR_TAG, "write() failed", e);
    }
}

Server side: this is the loop that reads data

...

int readBytes = 0;
int packetSize = 0;

while (true) {
    byte[] buffer = new byte[NET_BUFF_SIZE];

    try // first it reads the packet size from packet header
    {
        packetSize = dataInputStream.readInt();
    } catch (IOException e) {
        Log.e(ERROR_TAG, "readInt() failed", e);
        return;
    }

    while (readBytes < packetSize) {
        try {
            int readResult = dataInputStream.read(buffer);

            if (readResult != -1) {
                readBytes += readResult;
            } else {
                break;
            }
        } catch (IOException e) {
            Log.e(ERROR_TAG, "read() failed", e);
            break;
        }
    }
}

So, when the client calls write() to send the second packet, the server reads a wrong size from the stream.

DataOutputStream and DataInputStream are initialized in this way:

// Server
inputStream = clientSocket.getInputStream();
dataInputStream = new DataInputStream(inputStream);

// Client
outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);

What I am missing?


Solution

  • On your server side you should re-initialize the readBytes variable after the while(true) loop:

    while (true) {
         readBytes = 0;
         ....
    }
    

    All the best. A debugger would help you spot this problem sooner.