Client/Server Program in Java - Streams - java

I have a problem getting the output that i want from the code that i have implemented in order to create the server/client program...it's just a really simple one, and i don't know why i don't get what i want.
Here is the code of the server:
ServerSocket serverSocket = new ServerSocket(1025);
System.out.println("Porting...");
Socket socket = serverSocket.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = in.readLine();
System.out.println("Server read: " + s);
out.write("Got it");
socket.close();
System.out.println("Server Exit");
The client:
System.out.print("Connecting...");
Socket socket = new Socket("localhost",1025);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.write("Hello, Server");
String s = in.readLine();
System.out.println("Client Recieved: " + s);
socket.close();
System.out.println("Client Exit");
I try to get the Hello, Server output, instead i just get the "connecting" syso from the client (which i just did to see if it works)

Once you wrote on the stream you have to flush the stream by calling flush() method on the outputstream. Else the stream will be flushed once the stream buffer is full.
out.flush();
Also you have to make sure that enter the new line character to mention the end of line. Because readLine() waits for string with newline().
A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r')
out.write("Hello, Server\n");
out.flush();

Related

Print Writer write() and println()

I am currently learning Java Network programming. In one of my Programs I just have an EchoServer which sends the message of the client. But I recognized in the client that the Printwriter.write() method just sends when I close the writer while the .println() method works fine. I also tried it with and without auto-flush.
Works:
public static void main(String[] args) {
System.out.println("Simple Echo Client");
try{
System.out.println("Waiting for Connection ...");
InetAddress localAdress = InetAddress.getLocalHost();
try(Socket clientSocket = new Socket(localAdress,6000);
PrintWriter out =new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))){
System.out.println("Connected to Server");
Scanner scanner = new Scanner(System.in);
while(true){
System.out.print("Enter text: ");
String inputLine = scanner.nextLine();
if("quit".equals(inputLine)){
break;
}
out.println(inputLine);
String response = br.readLine();
System.out.println("Server response" + response);
}
}
}catch(IOException ex){
ex.printStackTrace();
}
}
Doesn't work:
public static void main(String[] args) {
System.out.println("Simple Echo Client");
try{
System.out.println("Waiting for Connection ...");
InetAddress localAdress = InetAddress.getLocalHost();
try(Socket clientSocket = new Socket(localAdress,6000);
PrintWriter out =new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))){
System.out.println("Connected to Server");
Scanner scanner = new Scanner(System.in);
while(true){
System.out.print("Enter text: ");
String inputLine = scanner.nextLine();
if("quit".equals(inputLine)){
break;
}
out.write(inputLine);
String response = br.readLine();
System.out.println("Server response" + response);
}
}
}catch(IOException ex){
ex.printStackTrace();
}
}
Could somebody explain to me why this is the case?
the Printwriter.write() method just sends when I close the writer while the .println() method works fine
There seems there may be two problems here, the first having to do with writing and the second with reading:
The code creates a PrintWriter with automatic line flushing. When you use println, the new line results in the writer flushing. When using write without a new line, the PrintWriter does not flush (you can call out.flush after out.write to force a flush of the Writer).
Presuming the receiving end is using Scanner.readLine(), it expects a new line or will wait until it receives one. println automatically appends the new line to the end of the String, with write you must explicitly send the new line out.write(line + "\n");
Yes I've absolutely seen this before. If you are using a PrintWriter or another Writer that has autoflush, you do not need to call flush(). But otherwise, to get the message to send, you've got to call flush() to get the content in the Writer / OutputStream to send.

Java sockets - Why do I need a PrintWriter to make this work?

I'm trying to learn socket programming in Java but unfortunately I'm running into some behaviour that I don't understand. I have a very simple client program that connect to a server socket and sends some text that gets echoed back. Said client program looks like this:
try(
Socket socket = new Socket("127.0.0.1", 5001);
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
){
String userInput = "";
while (!userInput.toLowerCase().equals("quit")) {
userInput = stdIn.readLine();
writer.write(userInput);
writer.flush();
System.out.println("Server response: " + reader.readLine());
}
}
catch(Exception e) {e.printStackTrace();}
When I run this program the first line that I enter gets sent to the server but after that I can enter as many lines as I want and nothing gets sent. I also never see anything printed out by the System.out.println() line.
But if I switch out the OutputStreamWriter for a PrintWriter everything works as it should! Here's the code with PrintWriter:
try(
Socket socket = new Socket("127.0.0.1", 5001);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
){
String userInput = "";
while (!userInput.toLowerCase().equals("quit")) {
userInput = stdIn.readLine();
writer.println(userInput);
System.out.println("Server response: " + reader.readLine());
}
}
catch(Exception e) {e.printStackTrace();}
Anyone have any idea why the first of the above two programs acts weird while the second one works? If anyone can tell me what the difference between writing with an OutputStreamWriter vs a PrintWriter is then that might tell me what's going on.
Note that the difference between write() and println() is that println() adds a linebreak after the data while write() does not.
So if your server uses readLine() to receive the data with a client using write() it might wait forever for the end of the line to read without receiving it.
So writer.write(userInput + "\n") might do the trick.

how to send TCP Requests in java

I am using Sockets to connect using TCP and I want to make different calls. e.g. Get InputValue
I have these type of different requests which I want to make from already running server.
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
String func="Get inputvalue";
byte[] tRequest = encoder.string2bytes(func);
out.write(tRequest);
out.flush();
System.out.println("write done");
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
It says it connected as just connected printout got printed. Write done print is also printed but no data is returned and the program keeps on running.
If I use telnet then this same request call returns data successfully.
So the question is how to make TCP calls in java?
Update: I solved this by:
PrintWriter toServer =
new PrintWriter(client.getOutputStream(),true);
BufferedReader fromServer =
new BufferedReader(
new InputStreamReader(client.getInputStream()));
toServer.println("Get inputvalue\r\n");
String line = "";
System.out.println("Client received: ");
while ((line = fromServer.readLine()) != null) {
System.out.println(line);
}
but the program keeps on running in the while loop and prints nothing. how to check that response is ended?

Java TCP socket blocks at readLine

I'm working on a TCP client/server application and face the issue that the client is always blocking at br.readLine(). I tried to add a \n, but it did not solve the problem. Also a char array is blocking, when I only use read instead of readLine.
Client:
BufferedReader brInput = new BufferedReader(new InputStreamReader(System.in));
String send = brInput.readLine();
Socket socket = new Socket(host, port);
BufferedReader brSend = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pr = new PrintWriter(socket.getOutputStream());
pr.println(send);
pr.flush();
System.out.println(brSend.readLine()); // is blocking
socket.close();
Server:
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept(); // blocks until request is received
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.isEmpty()) break;
}
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.write("Hello world\n");
pw.flush();
pw.close();
socket.close();
}
Your code as written does this:
The client writes one line, and then tries to read one.
The server reads multiple lines until it either gets an empty line, or the end-of-stream. Then it writes a line.
The problem is that server is waiting for the client to do something that it isn't going to do:
the client won't send an empty line (unless it read one from standard input),
the client won't close the stream ... until it gets the response from the server.
Hence the client is waiting for the server and the server is waiting for the client. Deadlock.
There are various ways to solve this. One simple way would be to change this (in the client)
println(send);
to this
println(send); println();
However, the one problem here is that your "protocol" does not cope with the case wants to send an empty line as data. That is because you are implicitly using an empty line (from the client) to mean "message completed".

Java Socket server side cannot read incoming line of text in play framework application

So I'm having some serious problems with Java's server side socket, which accepts connection, but it can't read anything from BufferedReader, which I have put to read the text stream from socket connection. Code for my threads run(), which I'm creating and running at the first time when any page is loaded.
public void run() {
try{
ServerSocket s = new ServerSocket(4100);
System.out.println("New tcp socket created");
Socket socket = s.accept();
System.out.println("New tcp update connection established.");
InputStream din = socket.getInputStream();
PrintWriter outp = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(din));
System.out.println("Streams created");
String inputline = "nothing yet...";
outp.println("hello from server");
while(true){
System.out.println("Got input from client:" + inputline);
inputline = in.readLine();
if(inputline == null || inputline.equals("exit")){
break;
}
}
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("Updater thread exits.");
}
This prints out everything properly, except for Got input from client: + what ever my client sends with PrintWriter which outputs to a socket.
Client side example:
Socket s = new Socket(serverip, serverDownloadsUpdatePort);
OutputStream dout = s.getOutputStream();
PrintWriter outp = new PrintWriter(dout);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(in.readLine());//This prints out properly, what server sends to client
outp.println("test connection");
outp.println("Can you hear me?");
outp.println("exit");
s.close();
Your client may not be sending end-of-line characters along with its input, causing your server to wait indefinitely at "in.readLine()".
The Javadoc for BufferedReader's readLine method (http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()) says: "Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed." Make sure that your client is sending input that conforms to this rule.
I was able to see client input using your server with the following client Runnable (but only if I include the "\n"):
public void run() {
try{
Socket writeSocket = new Socket("localhost", 4100);
PrintWriter out =
new PrintWriter(writeSocket.getOutputStream(), true);
out.write("Hello there!\n");
out.flush();
}
catch(Exception e){
e.printStackTrace();
}
}
EDIT: When using println as in the submitter's client example, you don't need to worry about adding "\n", but you do need to flush the socket. One way to make sure this happens is by setting autoFlush=true in the PrintWriter constructor.
I found out that I forgot to set PrintWriter as auto flushable at client side and thats why it didn't work becouse stream didn't got flushed at any time.

Categories