5

I am trying to write a simple Java program using ServerSockets that will send some HTML code to the browser. Here is my code:

ServerSocket serverSocket = null;
try {
    serverSocket = new ServerSocket(55555); 
} catch (IOException e) {
    System.err.println("Could not listen on port: 55555.");
    System.exit(1);
}

Socket clientSocket = null; 
try {
    clientSocket = serverSocket.accept();

    if(clientSocket != null) {           
        System.out.println("Connected");
    }
} catch (IOException e) {
    System.err.println("Accept failed.");
    System.exit(1);
}

PrintWriter out = new PrintWriter(clientSocket.getOutputStream());


out.println("HTTP/1.1 200 OK");
out.println("Content-Type: text/html");
out.println("\r\n");
out.println("<p> Hello world </p>");
out.flush();

out.close();

clientSocket.close();
serverSocket.close();

I then go to localhost:55555 in my browser and nothing displays. I know the connection is working because the program outputs "Connected" as checked in the if statement. I have also tried outputting the data from the inputStream and that works. But the text I am trying to output in the browser is not displaying at all, the program finishes running and I get a

"Problem loading page - the connection has been reset"

in my browser, but no text.

I have searched the internet and it seems everyone else coding it this way is having their text display fine, they are having other problems. How can I fix this?

2
  • what browser did you test? this code worked for me in chrome and firefox
    – fmodos
    Commented Apr 8, 2013 at 21:33
  • In Chrome I don't even get any results from the inputStream
    – ALR
    Commented Apr 8, 2013 at 21:39

6 Answers 6

4

I tested your code in Chrome, Firefox, IE, and Opera and it works.

However, I would suggest that you use multi-threading and essentially spawn a new thread to handle each new request.

You can create a class that implements runnable and takes a clientSocket within the constructor. This will essentially make your custom webserver capable of accepting more than one request concurrently.

You will also need a while loop if you want to handle more than one total requests.

A good read demonstrating the above: https://web.archive.org/web/20130525092305/http://www.prasannatech.net/2008/10/simple-http-server-java.html

If the web-archive is not working, I'm posting the code below (taken from above):

/*
* myHTTPServer.java
* Author: S.Prasanna
* @version 1.00
*/

import java.io.*;
import java.net.*;
import java.util.*;

public class myHTTPServer extends Thread {

static final String HTML_START =
"<html>" +
"<title>HTTP Server in java</title>" +
"<body>";

static final String HTML_END =
"</body>" +
"</html>";

Socket connectedClient = null;
BufferedReader inFromClient = null;
DataOutputStream outToClient = null;


public myHTTPServer(Socket client) {
connectedClient = client;
}

public void run() {

try {

System.out.println( "The Client "+
  connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");

  inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
  outToClient = new DataOutputStream(connectedClient.getOutputStream());

String requestString = inFromClient.readLine();
  String headerLine = requestString;

  StringTokenizer tokenizer = new StringTokenizer(headerLine);
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();

StringBuffer responseBuffer = new StringBuffer();
responseBuffer.append("<b> This is the HTTP Server Home Page.... </b><BR>");
  responseBuffer.append("The HTTP Client request is ....<BR>");

  System.out.println("The HTTP request string is ....");
  while (inFromClient.ready())
  {
    // Read the HTTP complete HTTP Query
    responseBuffer.append(requestString + "<BR>");
System.out.println(requestString);
requestString = inFromClient.readLine();
}

if (httpMethod.equals("GET")) {
if (httpQueryString.equals("/")) {
 // The default home page
sendResponse(200, responseBuffer.toString(), false);
} else {
//This is interpreted as a file name
String fileName = httpQueryString.replaceFirst("/", "");
fileName = URLDecoder.decode(fileName);
if (new File(fileName).isFile()){
sendResponse(200, fileName, true);
}
else {
sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
}
}
}
else sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
} catch (Exception e) {
e.printStackTrace();
}
}

public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception {

String statusLine = null;
String serverdetails = "Server: Java HTTPServer";
String contentLengthLine = null;
String fileName = null;
String contentTypeLine = "Content-Type: text/html" + "\r\n";
FileInputStream fin = null;

if (statusCode == 200)
statusLine = "HTTP/1.1 200 OK" + "\r\n";
else
statusLine = "HTTP/1.1 404 Not Found" + "\r\n";

if (isFile) {
fileName = responseString;
fin = new FileInputStream(fileName);
contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n";
if (!fileName.endsWith(".htm") && !fileName.endsWith(".html"))
contentTypeLine = "Content-Type: \r\n";
}
else {
responseString = myHTTPServer.HTML_START + responseString + myHTTPServer.HTML_END;
contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";
}

outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
outToClient.writeBytes(contentLengthLine);
outToClient.writeBytes("Connection: close\r\n");
outToClient.writeBytes("\r\n");

if (isFile) sendFile(fin, outToClient);
else outToClient.writeBytes(responseString);

outToClient.close();
}

public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception {
byte[] buffer = new byte[1024] ;
int bytesRead;

while ((bytesRead = fin.read(buffer)) != -1 ) {
out.write(buffer, 0, bytesRead);
}
fin.close();
}

public static void main (String args[]) throws Exception {

ServerSocket Server = new ServerSocket (5000, 10, InetAddress.getByName("127.0.0.1"));
System.out.println ("TCPServer Waiting for client on port 5000");

while(true) {
Socket connected = Server.accept();
    (new myHTTPServer(connected)).start();
}
}
}

Enjoy!

4
  • I have tried it in Chrome and Firefox with my firewall off. It has worked once out of about 15 times and that was in chrome. I don't understand what's going wrong.
    – ALR
    Commented Apr 8, 2013 at 22:12
  • Try adding a while(true) around all your code. Maybe your application is closing because more than one request is being made.
    – Menelaos
    Commented Apr 8, 2013 at 22:17
  • @MenelaosBakopoulos Site doesn't work and looks like malware, please change or remove Commented Sep 2, 2018 at 2:22
  • 1
    @THE Stephen Stanton I've updated the link to read off the internet-archive. Also included a copy of the original source code.
    – Menelaos
    Commented Sep 3, 2018 at 7:25
1

You need to need to set the PrintWriter to autoflush when it prints.

PrintWriter out = new PrintWriter(clientSocket.getOutputStream());

should be

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

1
  1. The line terminator in HTTP is \r\n. This means that you shouldn't use println(), you should use print() and add an explicit \r\n yourself to each line.

  2. The result of an HTTP GET is supposed to be an HTML document, not a fragment. Browsers are entitled to ignore or complain. Send this:

    <html>
    <head/>
    <body>
    <p> Hello world </p>
    </body>
    </html>
    
1

in my computer, at least to get the socket's inputStream:

clientSocket.getInputStream();

with out this line, sometimes chrome doesn't work

you need read the input from socket first

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = "";
while((line = bufferedReader.readLine()) != null){
    System.out.println(line);
    if(line.isEmpty())
        break;
}

1
  • For anyone else stuck on a similar issue, you don't need to read the input, but IF YOU DO make sure your code doesn't get stuck on reading (mine did). It worked after I switched to the code above and used BufferedReader with readLine, but readAllBytes wouldn't work
    – dtasev
    Commented Apr 13, 2018 at 22:43
1

You should accept the request sent by client(browser in this case),to do that just add the following lines:

Buffered reader in = new Buffered reader(new InputStreamReader(client_socket.getInputStream()));

Note: you need to replace the "client_socket" part with name of your own socket for the client.

Why we need to accept browser request? It's because if we don't accept the request browser doesn't get any acknowledgement from the server that the request that was sent is received,hence it thinks the server is not reachable any more.

My code:

public class Help {
    public static void main(String args) throws IOException{
        ServerSocket servsock new serverSocket(80)
        Socket cs servsock, accept();
        Printwriter out new Printwriter(Cs.getoutputstream), true)
        BufferedReader in new BufferedReader(new InputStreamReader(cs.getInputStream());
        out.println("<html> <body> <p>My first StackOverflow answer </p> </body> </html>");
        out.close();
        servsock.close();
    }
}
0

You need to send "HTTP/1.1 200 OK" first. followed by a newline then "Content-Type: text/html; charset: UTF-8" followed by 2 newlines. then send the HTML source for it to display as a styled webpage and not just a text output.

I used OutputStreamWriter

OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());

osw.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n");
osw.write("<html><head><title>Hello World</title></head><body></body><p>Hello World</p></body></html>");

Not sending "HTTP/1.1 200 OK" first results in source code being displayed without html parsing..

And to avoid "Connection being reset" error, you need to close your socket. Very Important !!

The whole code:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class WebServer
{
    ServerSocket serverSocket;
    Socket socket;

    FileReader fr;
    OutputStreamWriter osw;

    WebServer() throws IOException
    {
        serverSocket = new ServerSocket(8080);
        socket = serverSocket.accept();

        fr = new FileReader("index.html");
        osw = new OutputStreamWriter(socket.getOutputStream());

        osw.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n");

        int c;
        char[] ch = new char[4096];
        while ((c = fr.read(ch)) != -1)
        {
            osw.write(ch, 0, c);
        }

        osw.close();
        socket.close();
    }

    public static void main(String[] args) throws IOException
    {
        new WebServer();
    }
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.