Simple Java echo server issue - java

I'm trying to write my first socket server so I decided to start with something very simple be fore that just to figure the flow :) I'm writing a simple java echo server, but the thing is that (for some reason?!) I'm not getting the server response in the client, althought the request is received in the server.
package poc.client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
final Socket socket = new Socket((String) null, 50000);
final BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
final PrintWriter writer = new PrintWriter(
socket.getOutputStream(), true);
writer.println("ala bala\r\n");
writer.flush();
writer.close();
System.out.println(reader.readLine());
System.out.flush();
} catch (Exception ex) {
Logger.getAnonymouseLogger().throwing(TAG, "main", ex);
}
}
}
And the server part is
package poc.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
/**
* debugging purposes only
*/
#SuppressWarnings("unused")
private static final String TAG = Server.class.getSimpleName();
public static void main(String[] args) {
try {
final ServerSocket socket = new ServerSocket(50000);
while (true) {
final Socket clientSocket = socket.accept();
final BufferedReader reader = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
final PrintWriter writer = new PrintWriter(clientSocket
.getOutputStream(), true);
writer.println(reader.readLine());
writer.flush();
writer.close();
}
} catch (IOException e) {
Logger.getAnonymouseLogger().throwins(TAG, "main",ex);
}
}
}
I read all the Oracle basic socket tutorials/etc but I just can't figure what's wrong - I'm successfully writing to the server socket but I seem to be unable to get the response.

Do not close the writer before reading from the socket. Following code works
final Socket socket = new Socket((String) null, 50000);
final BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
final PrintWriter writer = new PrintWriter(
socket.getOutputStream(), true);
writer.println("ala bala\r\n");
System.out.println(reader.readLine());
//writer.flush();
writer.close();
As per the javadoc of close() method:
Closes the stream and releases any system resources associated with
it. Closing a previously closed stream has no effect.
Looks like if you close the stream, the underlying socket also gets closed. You can verify this by printing the stack trace in your current code. It gives java.net.SocketException: socket closed error.

Try this instead:
Socket socket = new Socket(InetAddress.getLocalHost(), 50000);
Also note that, there is no need for writer.flush(); since you are making it an auto-flush stream when you pass true to the second parameter of the PrintWriter constructor.

Related

BufferedReader Pending for Request/Response Socket Connection

I am trying to build a simple request/response server.
Client send a message to Server. Then, the server response a message to client.
Server-side Code
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
public class TcpServerAppl {
static int port = 1010;
static ServerSocket serverSocket;
static {
try {
serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
System.out.println("Server is running on " + port);
while(true){
Socket socket = null;
try{
socket = serverSocket.accept();
System.out.println("Someone is connecting to the server");
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(os);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
// read message from client
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// reader.close();
// send message to client
System.out.println("Server starts sending message to client");
printWriter.println("This is a message sent from server");
printWriter.flush();
// printWriter.close();
} catch(Exception e){
System.err.println(e.getMessage());
} finally {
if (socket != null){
try {
socket.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
}
}
}
Client-side code
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
public class TcpClientAppl {
public static void main(String[] args) throws UnknownHostException, IOException{
// start socket connection
Socket socket = SocketFactory.getDefault().createSocket("localhost", 1010);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// send message to server
printWriter.println("Send Message From Client" );
printWriter.flush();
// printWriter.close();
// read message from server
System.out.println("Client starts reading from Server");
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// bufferedReader.close();
// close scoket connection
socket.close();
}
}
The Server is blocked at the Buffered Reader. However, if I tried to close the Buffered Reader by closing in Print Writer in Client, the Client throw an exception of "Connection Closed".
It is known that closing in PrintWriter or BufferedReader would close the socket connection.
Update
Specifying a End of Request/Message would be one of solution. But in this case, I would not want to have an End of Request. I just want to have response for a request no matter no many line is in the request.
The client throw an exception of 'connection closed'
No it doesn't. If you uncomment the printWriter.close() line it will throw an exception 'socket closed'.
But to your real problem. The server reads lines until end of stream before it sends anything: end of stream will never occur until the peer closes the connection; and the peer isn't closing the connection, except as above; so it will never send anything and just stay blocked in readLine(); so the client will block forever in readLine() too.
As this is evidently an echo server, it should echo every line as it is received.
Question is missing exception thrown by client side. Maybe try to close everything (reader,writer) on server-side after your communication is done. BTW. you don't need to call flush before calling close. Also you can use try-catch-withResources with socket on server side

How do I make java sockets work? So confused

This is the code for my server, its supposed to take an input from the user, print it into console, then send it back to the user.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class DateServer {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(10219);
Socket s = listener.accept();
InputStreamReader in = new InputStreamReader(s.getInputStream());
BufferedReader input = new BufferedReader(in);
PrintWriter out = new PrintWriter(s.getOutputStream());
out.println("connected");
out.flush();
System.out.println("connected");
String test;
while (true) {
try {
test = input.readLine();
System.out.println(test);
out.println(test + " is what I recieved");
out.flush();
} catch(Exception X) {System.out.println(X);}
}
}
}
This is the code for the client:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.*;
public class DateClient {
public static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws Exception {
System.out.println("Enter IP Address of a machine that is");
System.out.println("running the date service on port 10219:");
String serverAddress = keyboard.next();
Socket s = new Socket(serverAddress, 10219);
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
}
}
This was designed to work across a LAN network. I have no idea why it doesn't work, all that happens is the client will get the message "connected" and nothing else will happen, no matter what is typed into the client end. I'm a noob when it comes to java, but after a bunch of googling and searching through the java libraries, I can't seem to make it work. What did I do wrong?
You send one line from the server to the client, but in your client you wait for two lines before accepting user input to be sent to the server.
Bearing in mind that input.readLine() will block until data is received, can you spot the deadlock here:
Server:
out.println("connected");
while (true) {
try {
input.readLine();
}
}
Client:
input.readLine();
while(true) {
try {
input.readLine();
out.println(keyboard.next());
}
}
(extraneous code trimmed away to show just the problematic sequence of statements)
Both your client and server mutually wait for each other trying to do input.readLine().
This can be easily seen if you remove server's out.println("connected") and its corresponding client's first input.readLine().
On the client, you should probably write first and only then read the response. Try reordering the following lines:
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
to get
out.println(keyboard.next());
out.flush();
System.out.println(input.readLine());
In the client, try changing
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
to
PrintWriter out = new PrintWriter(s.getOutputStream());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.nextLine());
out.flush();
} catch(Exception X){System.out.println(X);}
}
Your client is trying to read two lines, but your server sends just one, then polls for input, so both are locked. Also, sinc your server is reading line-by-line, your client should be sending data line-by-line.

PrintWriter won't write

I have the following problem.
I programmed a simple Echo Server and Echo Client but the problem is that in the loop of the Server, where I read from the Buffered Reader, the programme stuck and it won't write.
import java.net.*;
import java.util.*;
import java.io.*;
public class SimpleServer {
public static void main(String[] args) {
System.out.println("Dies ist ein simpler Echo Server");
int port = 6000;
try {
ServerSocket server = new ServerSocket(port);
//server.setSoTimeout(30000);
System.out.println("Warte auf anfrage");
Socket client = server.accept();
InputStream is = client.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String message = null;
while ((message = reader.readLine())!=null) {
System.out.println("Nachricht vom Client "+message);
}
OutputStream os = client.getOutputStream();
PrintWriter writer = new PrintWriter(os);
System.out.println(message);
writer.println(message);
writer.flush();
writer.close();
} catch(IOException e) {
e.printStackTrace();
} // end of try
} // end of main
} // end of class SimpleServer
But when i put the .println() and .flush() in the loop everything works great.
import java.net.*;
import java.util.*;
import java.io.*;
public class SimpleServer {
public static void main(String[] args) {
System.out.println("Dies ist ein simpler Echo Server");
int port = 6000;
try {
ServerSocket server = new ServerSocket(port);
//server.setSoTimeout(30000);
System.out.println("Warte auf anfrage");
Socket client = server.accept();
InputStream is = client.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
OutputStream os = client.getOutputStream();
PrintWriter writer = new PrintWriter(os);
String message;
while ((message = reader.readLine())!=null) {
System.out.println("Nachricht vom Client "+message);
writer.println(message);
writer.flush();
}
writer.close();
} catch(IOException e) {
e.printStackTrace();
} // end of try
} // end of main
} // end of class SimpleServer
My question is why does it stuck in the loop ?
You are reading the inpit until end of stream before you send anything. End of stream on a socket only occurs when the peer closes the connection. The peer hasn't closed the connection, because he wants to read your reply from it.
You should echo every line as you read it, not try to assemble them all and then echo them all in one great chunk. Apart from the fact that it can't work, your technique also wastes both time and space.

Java – Server Only Responds when the Client has Stopped

I recently programmed a simple Java server, and a client to test the server. The server is supposed to receive messages from the client, and send a random substring of the message back. The problem is this: When I send the message using the client program, the server does not respond. Then, when I kill the client program, the server leaps into action, and attempts to send the data back to the client. The server reads the data correctly but starts processing it only when I stop the client program.
This is the client code:
import java.io.*;
import java.net.*;
class ServerTest{
public static void main(String args[]) throws Exception{
Socket clientSocket = new Socket(myIpAdress, 8001);
//Send the message to the server
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String sendMessage = "randSubstring:StackOverflowIsAwsome";
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent: "+sendMessage);
String message = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())).readLine();
System.out.println("Message received from the server : " +message);
clientSocket.close();
}
}
My server code consists of two classes. This one is the listener:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerListener {
public static void main(String args[]) throws Exception {
String clientSentence;
ServerSocket socket = new ServerSocket(8001);
while(true) {
Socket connectionSocket = socket.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//DataOutputStream output = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = input.readLine();
if(clientSentence.startsWith("randSubstring:")){
Thread connection = new Thread(new ServerConnection(connectionSocket, clientSentence));
connection.start();
}
Thread.sleep(300);
}
}
}
This is the thread that will not start until the client is stopped:
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Random;
public class ServerConnection implements Runnable{
private Socket serverConnection;
private String sentence;
public ServerConnection(Socket connection, String clientSentence){
serverConnection = connection;
sentence = clientSentence;
}
#Override
public void run() {
Random r = new Random();
String substring = sentence.substring(0, r.nextInt(sentence.length()));
try {
OutputStream os = serverConnection.getOutputStream();
OutputStream out = new BufferedOutputStream(os);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write(substring);
bw.close();
out.close();
os.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am using a Macintosh with Yosemite. Is this happening because I am trying to run the programs on the same computer, or would the problem occur if the programs were run from different computers? Any help is appreciated.
In the server you do a readLine(..), which means that it will wait for a end-of-line character.
But in your sender code, you just send a string with no line ending.
So either you make sure you also send a end of line char or your server wait's for something else as "delimiter"
You're reading a line but you aren't writing a line. Add a line terminator to the sent message. Otherwise readLine() won't return until the peer closes the connection.
NB The I/O in the try block after the accept should be in the Runnable, not where it is. Don't do I/O in the accept loop.

Why is my HTTP response not showing up in my browser?

I am trying to write an HTTP server in Java. After going through examples and adding in some stuff for debugging, this is what I have so far:
import java.net.*;
import java.io.*;
import java.util.*;
public class AddyServer {
public static void main(String[] args) {
int portNumber = Integer.parseInt(args[0]);
try{
System.err.println("Trying...");
ServerSocket serverSocket = new ServerSocket(portNumber);
System.err.println("Waiting...");
//PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
while(true) {
System.err.println("Waiting...");
Socket clientSocket = serverSocket.accept();
System.err.println("accepted");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String line;
while((line=in.readLine())!=null) {
if(line.isEmpty())
break;
out.print(line+"\r\n");
System.out.print(line+"\r\n");
}
out.print("HTTP/1.1 200\r\n"); //EDITED
out.print("Content-Type: text/html\r\n");
out.print("Connection: close\r\n");
out.print("\r\n");
out.print("<!doctype html>\n");
out.print("<title>Test title</title>\n");
out.print("<p>Test</p>\n");
System.out.print("HTTP/1.1 200 \r\n");
System.out.print("Content-Type: text/html\r\n");
System.out.print("Connection: close\r\n");
System.out.print("\r\n");
System.out.print("<!doctype html>\n");
System.out.print("<title>Test title</title>\n");
System.out.print("<p>Test</p>\n");
in.close();
out.close();
clientSocket.close();
}
} catch (IOException e) {System.err.println(e);} //EDITED
}
}
I do not understand why my internet browser is not displaying the HTTP response body in the browser when I try connecting to my server.
Add a flush after writing to socket (via PrintWriter). Also you need to close the serverSocket at some point, otherwise, you'll have issues just testing it with port being already bound.
edit This shows exactly where you want to flush. Tested and works for me.
Working fixed code:
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.util.*;
public class AddyServer {
public static void main(String[] args) throws Exception {
int portNumber = Integer.parseInt(args[0]);
System.err.println("Trying...");
ServerSocket serverSocket = new ServerSocket(portNumber);
System.err.println("Waiting...");
// PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
// true);
while (true) {
System.err.println("Waiting...");
Socket clientSocket = serverSocket.accept();
System.err.println("accepted");
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String line;
while ((line = in.readLine()) != null) {
if (line.isEmpty())
break;
out.print(line + "\r\n");
System.out.print(line + "\r\n");
}
out.print("HTTP/1.1 200 \r\n");
out.print("Content-Type: text/html\r\n");
out.print("Connection: close\r\n");
out.print("\r\n");
out.print("<!doctype html>\n");
out.print("<title>Test title</title>\n");
out.print("<p>Test</p>\n");
out.flush(); // <--- Fix is here
System.out.print("HTTP/1.1 200 \r\n");
System.out.print("Content-Type: text/html\r\n");
System.out.print("Connection: close\r\n");
System.out.print("\r\n");
System.out.print("<!doctype html>\n");
System.out.print("<title>Test title</title>\n");
System.out.print("<p>Test</p>\n");
in.close();
out.close();
clientSocket.close();
}
}
}
Your output isn't getting flushed (actually sent). Use flush() on the PrintWriter and it should work.
A PrintWriter doesn't necessarily flush automatically.
My guess is that you close the socket (hence interrupting the connection) before the PrintWriter has been able to flush upon closing.
As an alternative to flushing right before closing (recommended), you could construct your PrintWriter with automatic line flushing (not recommended) as
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
In which case calls to printf, println or format will flush it (but not calls to print).

Categories

Resources