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).
Related
I want my client to send a message to the server and the server send back the message received
but there is an issue with my client because It never reach the close() statement because of readLine()
therefore it just hangs there, what can I do to make it work ?
Server :
import java.net.*;
import java.io.*;
public class Server{
public static void main(String[] args){
try{
ServerSocket server=new ServerSocket(3535);
while(true){
Socket socket=server.accept();
BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
String message=in.readLine();
System.out.println(message);
out.print(message);
out.flush();
in.close();
out.close();
socket.close();
} }
catch(Exception e){
System.out.println(e);
e.printStackTrace();
}
}
}
Client :
import java.net.*;
import java.io.*;
public class Client{
public static void main(String[] args){
try{
BufferedReader user_in =new BufferedReader(new InputStreamReader(System.in));
while(true){
Socket socket=new Socket("localhost",3535);
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
out.print(user_in.readLine());
out.flush();
String message_from_server = in.readLine();
System.out.println("Message from server : " + message_from_server);
out.close();
in.close();
socket.close();
}
}
catch(Exception e){
System.out.println(e);
e.printStackTrace();
}
}
}
The "problem" lies in readLine() in the server.
This is wanted behavior. BufferedReader implements readLine() in a way so that it blocks until it receives either one of: '\n', '\r', carriage return followed by a line feed, or an EOF
The client is sending neither of them.
Instead of using the print() method of PrintWriter, you could use println().
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.
I have a simple client/server chat in java using Socket. The problem is the program connect to each other but I can't get/receive data from both side for some reasons. When I disconnect the server the client give me an error " Connection reset" which shows that they are connected but they don't exchange data.
The code are the same code taken from Java Tutorial taken from here.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication3;
/**
*
* #author Amr
*/
import java.net.*;
import java.io.*;
public class KnockKnockServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4440);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.out.println(Inet4Address.getLocalHost());
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
while ((inputLine = in.readLine()) != null) {
outputLine = "heelo";
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
import java.io.*;
import java.net.*;
public class KnockKnockClient {
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket(Inet4Address.getLocalHost(), 4440);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
After setting up the connection, the first thing your server does is
while ((inputLine = in.readLine()) != null)
that is, it waits for the client to say something.
The first thing your client does is
while ((fromServer = in.readLine()) != null)
that is, it waits for the server to say something.
Make one of the two send something first and it should work.
The bit you're missing from that tutorial is this block:
// initiate conversation with client
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
Currently, you are not initialising the conversation, hence the socket read blocking pointed out by other posters.
You have a single thread on both the client and the server that reads from their respective BufferedReader, using the readLine() method, which blocks.
Since both the client and server are expecting to read from one another before either of them sends anything, they'll both just sit there and block. You either need to fork and have a thread that reads from the BufferedReader and one that writes to the PrintWriter, or you have to have:
outputLine = "heelo";
out.println(outputLine);
outside of your while loop.
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.
I hava a problem with my code. I make a server with Java which waits for connections. When a client connects, if we(the server) send the command "showinfo", the cliend send its IP address back to the server.
The problem is that it is a multi-threaded server and many clients connect. So, if, for example, 2 clients connect to the server we have to type 2 times showinfo and then the clients give us the information. How can I make the clients respond immediately with typing "showinfo" for each one and don't wait until I type showinfo for all the clients. It's a bit tiring to type 50 times showinfo if there are 50 clients before you can execute your command. Thank you in advance (i have tried some thread synchronization and some sleep() join() commands but I haven't reach a conclusion yet I hope you can help a bit.)
Here 's the server code
import java.io.*;
import java.net.*;
import java.security.*;
public class Server implements Runnable{
private Socket server;
private static String command,info,message;
BufferedReader infromclient =null;
InputStream infromclient2=null;
DataOutputStream outtoclient =null;
static BufferedReader infrommaster=null;
private static int port=6789;
Server( Socket server ){
try{
this.server=server;
infromclient =new BufferedReader(new InputStreamReader(server.getInputStream()));
outtoclient =new DataOutputStream(server.getOutputStream());
infrommaster=new BufferedReader(new InputStreamReader(System.in));
}catch( IOException e ){
System.out.println("Exception accessing socket streams: "+e);
}
}
// main()
// Listen for incoming connections and handle them
public static void main(String[] args) {
ThreadGroup clients = new ThreadGroup("clients");
System.out.print("Waiting for connections on port " + port + "...");
System.out.println("\nIn total there are:"+clients.activeCount()+" clients\n");
try{
ServerSocket server = new ServerSocket(port);
Socket nextsocket;
// waiting for connections
while(true){
nextsocket = server.accept();
Thread client= new Thread(clients,new Server(nextsocket),"client"+(clients.activeCount()+1));
System.out.println("Client connected");
System.out.println("There are "+clients.activeCount()+" clients connected");
client.start();
}
}catch (IOException ioe){
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
public void run (){
try{
command=infrommaster.readLine();
outtoclient.writeBytes(command+"\n");
// showinfo
if(command.equals("showinfo")){
info=infromclient.readLine();
System.out.println("\nClient information\n\n" +info+"\n");
}
server.close();
}catch (IOException ioe){
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
and here is the code for the client:
import java.io.*;
import java.net.*;
import java.lang.*;
public class Client{
public static void main(String args[]) throws Exception{
String command2;
String info;
Socket clientSocket=null;
Socket scket=null;
BufferedReader inFromUser=null;
DataOutputStream outToServer=null;
BufferedReader inFromServer=null;
BufferedWriter tosite=null;
try{
clientSocket = new Socket(InetAddress.getLocalHost().getHostName(), 6789);
inFromUser =new BufferedReader(new InputStreamReader(System.in));
outToServer =new DataOutputStream(clientSocket.getOutputStream());
inFromServer =new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}catch(UnknownHostException | IOException e ){
System.out.println("Problem "+e);
}
command2=inFromServer.readLine();
System.out.println("From Server:" +command2);
// showinfo
if (command2.equals("showinfo")){
try{
InetAddress myip=InetAddress.getLocalHost();
info =("IP: " +myip.getHostAddress()+"\n");
System.out.println("\nSome system information\n" + info);
outToServer.writeBytes(info);
}catch (Exception e){
System.out.println("Exception caught ="+e.getMessage());
}
}
outToServer.flush();
outToServer.close();
inFromUser.close();
inFromServer.close();
clientSocket.close();
}
}
** the command clientSocket = new Socket(InetAddress.getLocalHost().getHostName(), 6789); means that it tests my pc(my ip in port 6789) .
If one thread is blocking on the readline, the other should eventually get control. That's the whole point of multithreading. I think I know your problem. Move the code where you are reading the input command into the run() method of the server instead. Then you should be good. I think the problem is that your threads are starting after you are polling for input.
Move these lines from the Server constructor to Server's run() method:
infromclient =new BufferedReader(new InputStreamReader(server.getInputStream()));
outtoclient =new DataOutputStream(server.getOutputStream());
infrommaster=new BufferedReader(new InputStreamReader(System.in));