There is a java client that sends a long json to a server that is written in python . If the length of json 'and not very large, then everything goes fine. If the string is large, then it does not reach all. Breaks somewhere in 1500 characters (not exactly).

Customer:

  private static void connect(String ip, int port) throws IOException { long sessionId = new Random().nextLong(); queue.add(sessionId); while (!(queue.size() <= 0 || queue.get(0).equals(sessionId))) try { Thread.sleep(200); } catch (InterruptedException ignored) { } socket = new Socket(ip, port); } static String sendJsonForResult(String json) throws IOException { return sendJsonForResult(json, TIMEOUT); } static String sendJsonForResult(String json, int timeout) throws IOException { try { connect(ip, port); if (socket == null) throw new IOException("Socket is null"); socket.setSoTimeout(timeout); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.write(json.getBytes("UTF-8")); dos.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String response = in.readLine(); if (response == null || response.equals("")) throw new IOException(String.format("Incorrect response (%s)", response)); Log.d("CLIENT", "Answer:\n\t" + response); return response; } finally { disconnect(); } } private static void disconnect() { try { socket.close(); } catch (Exception ignored) { } if (queue.size() > 0) queue.remove(0); } 

Server:

 try: tcp_socket.bind((host, port)) except socket.error as e: print('[SERVER] ERROR: ' + str(e)) tcp_socket.listen(10) while true: conn, addr = tpc_socket.accept() try: data = conn.recv(1048576) data = data.decode('utf-8') if data != '': print('[SERVER] Received data from ' + addr[0] + ':\n\t' + data) 

How do I solve this problem?

  • 2
    By definition, a socket is not required to send an entire message at a time. When sending a message, you need to look at how many bytes are sent, and not sent - send again. Similarly, when receiving, it is necessary to calculate how many bytes are received or whether there is a sign "end of message". If the byte is not enough - then you need to read the message. - nick_n_a
  • one
    If you want to receive a "not ragged" message - discard the socket, use top-level protocols through ready-made libraries (for example, http). If you are using a socket, do as described above. - nick_n_a
  • You need to call conn.recv(1048576) in a loop until you get all the data, for example: github.com/gil9red/SimplePyScripts/blob/… - gil9red

1 answer 1

Problem solved. Thanks @nick_n_a and @ gil9red for the tip. First, in python, I did the following, as in the comments and recommended:

 while true: conn, addr = tpc_socket.accept() try: databytes = bytesarray() while True: databuff = conn.recv(4096) if not databytes: break databytes += databuff data = databytes.decode('utf-8') if data != '': print('[SERVER] Received data from ' + addr[0] + ':\n\t' + data) 

But the next problem appeared - the request was not sent until the socket on the client is closed. I tried to close the OutputStream , but the socket was also closed with it, and I also had to read the answer.

The solution turned out to be the following: instead of OutPutStream.close() use Socket.shutdownOutput() .

Here is the client code:

 private static void connect(String ip, int port) throws IOException { long sessionId = new Random().nextLong(); queue.add(sessionId); while (!(queue.size() <= 0 || queue.get(0).equals(sessionId))) try { Thread.sleep(200); } catch (InterruptedException ignored) { } socket = new Socket(ip, port); } static String sendJsonForResult(String json) throws IOException { return sendJsonForResult(json, TIMEOUT); } static String sendJsonForResult(String json, int timeout) throws IOException { try { connect(ip, port); if (socket == null) throw new IOException("Socket is null"); socket.setSoTimeout(timeout); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); dos.write(json.getBytes("UTF-8")); dos.flush(); socket.shutdownOutput(); String response = in.readLine(); if (response == null || response.equals("")) throw new IOException(String.format("Incorrect response (%s)", response)); Log.d("CLIENT", "Answer:\n\t" + response); return response; } finally { disconnect(); } } private static void disconnect() { try { socket.close(); } catch (Exception ignored) { } if (queue.size() > 0) queue.remove(0); }