I have a simple client/server I'm working on. I have to send the a cookie from the server to the client(it's just a string), but my client won't read the inputStream.
Server:
out = new PrintStream(sock.getOutputStream());
out.println(text);
out.println(temp2State);
out.println(temp2State);
Client:
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String textClient = in.readLine();
String temp1= in.readLine();
String temp2= in.readLine();
This is just the code that seems to be giving me trouble. On the client I receive textClient but then the next 2 are blank. If I do a print out of temp2state on the server before it's sent I get a string, yet if I print out temp1 on the client, its empty. So it's seems to be lost in translation. That being said if use a for loop to receive the data(which was shown in class) it will return temp1 but then textClient is empty. This is being done on a socket so I do have try/catch but it didn't seem relevant.
Alternate input read:
for (int i = 1; i <= 5; i++) {
fromServer = in.readLine();
if (fromServer != null) {
String textClient = in.readLine();
String temp1= in.readLine();
String temp2= in.readLine();
}}
FOUND THE ISSUE:
Turns out I had a string trying to be sent with System.lineSeperator() attached which was sending an empty line.
As per Java API,
public PrintStream(OutputStream out) constructor Creates a new print stream and it will not flush automatically.
Please try the with constructor which accepts true to auto flush, whenever data is written in it.
Please modify your code like
out = new PrintStream(sock.getOutputStream(), true);
Related
I have developed a small java client that suppose to communicate with a tool installed on unix-server.
I'm working with Socket first time so could do something wrong. I am also limited to Java 6.
In brief code looks like this
I use Socket to establish connection.
Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(endpoint, port);
socket.connect(socketAddress, 5000);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Here is how I send message
out.println("Hello");
out.flush();
And here is how I read response
String res = "";
int letter;
while(letter = in.read() != -1) {
char c = (char) letter;
res += c;
}
F.x. If I send a message "Hello", I will receive answers with 2 lines (see example below)
> Hi there
> My name is Robot
The things stuck when I read next character after "Robot\n", I expected that in.read() != -1 will be true and thus it will stop itself, but that is not a case and instead everything just stuck.
What could be the reason to this and how to solve? Thanks.
Please let me know if I need to provide more information.
I had to close my output writer before reading from it, otherwise it blocks.
if (!socket.isOutputShutdown()) {
socket.shutdownOutput();
}
The answer came from a person who later deleted own answer :-/
I'm trying to send a string from my c client to a Java server, after which the server sends a text file to the client.
This is the part of client code that sends the string.
int n = write(sock_fd,"Ready",5);
if (n < 0)
printf("ERROR writing to socket\n");
recv_file(sock_fd, filename);
And this is the server part of java code:
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("Message received from client is " + message);
String FILENAME = "data.txt";
sendFile(socket, "data.txt");
Now I have verified that if I remove the part in the server code where it tries to read the string from c client, the rest of the code works fine and the file is transmitted. But if do not comment the string receiving code, both the server and client keep waiting.
I will be grateful if somebody solves this issue for me.
P.S. I know this question has been asked before but that didn't help me, so I started a new thread.
br.readLine() wants to read a line. The client never sends a newline, so the server is waiting for a newline... forever!
Add a newline to the command sent by the client:
int n = write(sock_fd,"Ready\n", 6);
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.
The point of readLine() is to read data where it really is guaranteed that the input will end with a newline. Generally, when parsing input, there has to be some token - some character or combination of characters in the input, which you can use to decide whether to
Wait for more input
Do something with the information you've gotten already
And possibly decide whether to go back to waiting for more input afterwards
If you cannot guarantee that a newline will be sent, then readLine() is the wrong tool for the job. Use something like the character-array read method of InputStreamReader instead. You will have to iterate the array of characters you read in, and figure out when you have enough input to work with. You could also use the one-character-at-a-time read() method of InputStreamReader which will result in simpler but probably less efficient code.
If you use the character-array version of read(), and if you go back to collecting input after parsing some, don't forget to put whatever is left over when you do get enough to parse back into the queue to handle on the next round.
I am currently having an issue with a Server - Client interaction.
I am needed to read multiple println that a server sends to a client, this works but after it has read the lines it doesn't seem to go back to waiting for the user of the client to enter a new command
This is the method that opens up the streams
private void openStreams() throws IOException
{
final boolean AUTO_FLUSH = true;
is = socket.getInputStream();
os = socket.getOutputStream();
fromServer = new BufferedReader(new InputStreamReader(is));
toServer = new PrintWriter(os, AUTO_FLUSH);
}
This is the method that sends the request then reads them out
private void sendRequest() throws IOException
{
String request;
String reply;
Scanner sc = new Scanner(System.in);
request = sc.nextLine();
while(!(request.equals(CLIENT_QUITTING)))
{
toServer.println(request);
while((reply = fromServer.readLine()) != null)
{
System.out.println(reply);
}
request = sc.nextLine();
}
}
It seem to be getting stuck on the inner while loop
Can anyone point me in the direction of where I am going wrong?
The receiving code somehow needs to know when to stop reading text, and when to expect the next command.
For example, the Simple Mail Transfer Protocol (SMTP) defines that the body of the mail consists of several lines, and the line .\r\n marks the end.
Another possibility is what HTTP does for chunked encoding (with bytes, but the concept is the same). It sends the body as a sequence of chunks. Each chunk consists of a length field and the data (which is length bytes long). In your case you would probably send the number of lines that the receiver may expect, and then the lines themselves.
I am sending several messages in my application from client to server one of them is "\r\n.\r\n" how can the server identify this message between others?
I have used equals() method but it did not work:
is = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
String st = is.readLine();
if(st.equals("\r\n.\r\n"))
// ........
If this is just "." on a separate line like in the SMTP, then you could just use st.equals("."), as readLine() strips EOL characters. But if you need to make sure it's exactly "\r\n.\r\n", and not "\n.\n" for example, then you should probably avoid readLine() and implement line reading by yourself, possibly reading character-by-character.
is = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
is.mark(5);
char[] tmp = new char[5];
is.read(tmp, 0, 5);
if(new String(tmp).equals("\r\n.\r\n"))
// you have that message
else
is.reset();