Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java sending message between server and client without newline character

I have a client which is connecting to a server. The server and the client exchange datas in string format. The problem is that, the server does not take '\n' character at the end of the message and because of this the client blocked in readLine() method. Unfortunately the server-side can't be changed. How can read from stream that kind of message which 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();
            }
        }
    }
}
like image 506
Genesist Avatar asked Jul 17 '13 21:07

Genesist


2 Answers

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

StringBuffer sb = new StringBuffer();
while (br.ready()) {
    char[] c = new char[] { 1024 };
    br.read(c);
    sb.append(c);
}
like image 140
fmodos Avatar answered Nov 15 '22 06:11

fmodos


The easiest solution is to read the message character per character, but the main problem here is to know when the message is complete. In a line-oriented protocol this is simple, the newline that was sent is the "separator" between messages. Without, there are two possible situations where this problem is easy to solve:

Case 1: the message always has a fixed character at the end, that can't occur in the message

// let's 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's 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'll have to add some code to check the sanity of what you received, you may have received EOF during read.

If there is no obvious message separator and message have a variable length it will be a lot harder.

like image 33
fvu Avatar answered Nov 15 '22 05:11

fvu