TCP send / receive missing bytes

I am using C # to build Windows server software and Java to build client software. It works great in most cases, except for a few exceptions that I don't understand.

I usually use .ReadLine () and .WriteLine () on both ends for communication, unless I am trying to send binary data. This is when I write and read bytes directly. This is how the software is supposed to work:

  • Client requests binary data
  • The server responds to the length of the binary data as a string
  • The client gets the length and converts it to an integer and starts reading (length) bytes
  • The server starts writing (length) bytes

It works in most cases, but sometimes the client application does not receive complete data and blocks. The server always resets immediately after writing data, so reset is not a problem.

Also, I noticed that this usually happens with large files, small files (up to ~ 1MB) are usually not a problem.

NOTE The C # server seems to be transmitting data completely, so the problem is most likely somewhere in the Java code.

EDIT . Here are some client side logs.

Working download : pastebin.com/hFd5TvrF

Failed download : pastebin.com/Q3zFWRLB

It looks like the client is waiting at the end of 2048 bytes (as it should, as length - processed = 2048

in this case), but for some reason the client is blocking.

Any ideas what I am doing wrong? Below are the source codes of the server and client:

C # server:

public void Write(BinaryWriter str, byte[] data)
{
    int BUFFER = 2048;
    int PROCESSED = 0;
    // WriteString sends the String using a StreamWriter (+ flushing)
    WriteString(data.Length.ToString());
    while (PROCESSED < data.Length)
    {
        if (PROCESSED + BUFFER > data.Length)
            BUFFER = data.Length - PROCESSED;

        str.Write(data, PROCESSED, BUFFER);
        str.Flush();

        PROCESSED += BUFFER;
    }
}

      

Java client:

public byte[] ReadBytes(int length){
    byte[] buffer = new byte[length];
    int PROCESSED = 0;
    int READBUF = 2048;
    TOTAL = length;
    progress.setMax(TOTAL);
    InputStream m;
    try {
        m = clientSocket.getInputStream();
        while(PROCESSED < length){
            if(PROCESSED + READBUF > length)
                READBUF = length - PROCESSED;

            try {
                PROCESSED += m.read(buffer, PROCESSED, READBUF);
            } catch (IOException e) {
            }
            XPROCESSED = PROCESSED;
        }
    } catch (IOException e1) {
        // Removed because of sensitive data
    }

    return decryptData(buffer);
}

      

+3


source to share


1 answer


I found a fix. At the moment the server is sending the length and right after sending the byte array. For some reason this doesn't work.

So, I changed this:



  • Send length and wait for client response with "OK"
  • Start writing bytes

Not sure why, but it works. Run it in a loop while(true)

and it was sending data 1000 times in 4 minutes in a row and no problem, so I guess that's fixed

0


source







All Articles