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();
}
}
}
}
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With