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:
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;
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. -, ?