Java socket does not always receive all bytes

I have a problem with my Java application using sockets. After connecting to the socket on the server, we can download the file.

The procedure is as follows:

  • the client sends a message to the server with the file name to download
  • server responds with file size
  • then the server sends all bytes of the file to the socket

Here is my Java code:

//init keyManagerFactory and trustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { trustManager }, new SecureRandom());
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(new Socket(ipAddress, port), ipAddress, port, false);
socket.startHandshake();

DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
... 

int toRead = xxxx; //received from server response
List<Byte> bytes = new ArrayList<>();
while(toRead > 0) {
    byte b = in.readByte();
    bytes.add(b);
    toRead--;
}

The problem is that sometimes I get all bytes from the server, but in other cases I get only part of it, and there is no more data, for example. the server sends the file size = 1500, my application tries to get it from the socket, but there are only 1100 bytes, at another time there are 1200 and at another time 1500.

It can be said - this is a problem with the server. But I wrote a Python program with the same functionality, and it always works fine!

Here's the python code:

def recv(sock, toread):
    buf = bytearray(toread)
    view = memoryview(buf)
    while toread:
        nbytes = sock.recv_into(view, toread)
        if nbytes == 0:
            sock.close()
            raise Disconnected
        view = view[nbytes:]
        toread -= nbytes
    return buf

plainsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = ssl.wrap_socket(plainsock, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1)
sock.connect(someIP, somePort)

...

toRead = xxxx //received from server response

data = recv(sock, toRead)

Sockets Java. -, ?

+4

Source: https://habr.com/ru/post/1652291/


All Articles