Sending Java messages between server and client without a newline

I have a client that connects to the server. Server and client data exchange in string format. The problem is that the server does not accept the character "\ n" at the end of the message, and because of this, the client is blocked in the readLine() method. Unfortunately, the server side cannot be changed. How can one read from a stream such a message that does not have "\ n" at the end?

My client code:

 public class json { private static Socket socket; public static void main(String args[]) { String sendMessage = ""; Gson gson = new Gson(); JSON_package authentication = new JSON_package(); authentication.setType("Identifying"); authentication.setSource("exampleClient"); Package_Parser pp = new Package_Parser(); sendMessage = gson.toJson(authentication); sendMessage = authentication.buildPackage(sendMessage); try { String host = "host_address"; int port = port_number; InetAddress address = InetAddress.getByName(host); System.out.println("Connecting."); socket = new Socket(address, port); System.out.println("Connected."); //Send the message to the server OutputStream os = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os); BufferedWriter bw = new BufferedWriter(osw); bw.write(sendMessage); bw.flush(); System.out.println("Message sent to the server : "+sendMessage); //Get the return message from the server InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); StringBuffer buffer = new StringBuffer(); String message = br.readLine(); message = pp.Parser(message); System.out.println("Message received from the server : " +message); } catch (Exception exception) { exception.printStackTrace(); } finally { //Closing the socket try { socket.close(); System.out.println("Closed."); } catch(Exception e) { e.printStackTrace(); } } } } 
+4
source share
3 answers

You can try using ready and read (char c) . Here is one example:

 StringBuffer sb = new StringBuffer(); while (br.ready()) { char[] c = new char[] { 1024 }; br.read(c); sb.append(c); } 
+3
source

The easiest solution is to read the message character by character, but the main problem here is to find out when the message will be completed. In a line-oriented protocol, this is simple, the new line that was sent is the โ€œdelimiterโ€ between the messages. Without this, two situations are possible when this problem is easily solved:

Case 1: a message always has a fixed character at the end that cannot happen in the message

 // let pretend ! is the end of message marker final char endMarker = '!'; // or of course StringBuffer if you need to be treadsafe StringBuilder messageBuffer = new StringBuilder(); // reads to the end of the stream or till end of message while((value = br.read()) != -1) { char c = (char)value; // end? jump out if (c == endMarker) { break; } // else, add to buffer messageBuffer.append(c); } // message is complete! String message = messageBuffer.toString(); 

Case 2: The message has a fixed length

 // let pretend message is always 80 long int messageLength = 80; StringBuilder messageBuffer = new StringBuilder(); int charactersRead = 0; // reads to the end of the stream or till end of message while((value = br.read()) != -1) { char c = (char)value; // end? jump out if (++charactersRead >= messageLength) { break; } // else, add to buffer messageBuffer.append(c); } // message is complete! String message = messageBuffer.toString(); 

In both cases, you will need to add code to verify the correctness of what you received, you may have received EOF while reading.

If there is no obvious message separator, and the message has a variable length, it will be much more complicated.

+1
source

The point of readLine() is to read data, where it is actually guaranteed that the input ends with a new line. As a rule, when analyzing the input, there should be some token - some character or a combination of characters at the input, which you can use to decide whether to

  • Wait for more input
  • Do something with the information you have already received.
    • And perhaps decide whether to return to expecting more input

If you cannot guarantee the sending of a new line, then readLine() is the wrong tool for the job. Instead, use the InputStreamReader read method , something like an array. You will have to iterate over the array of characters you are reading and find out when you have enough input to work. You can also use the read() method with one character in time InputStreamReader , which will lead to simpler, but probably less efficient code.

If you are using the read() character array version, and if you return to collecting input after parsing some, do not forget to put all that is left when you have enough to parse the queue to process the next round.

0
source

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


All Articles