Java Server: Socket sending HTML code to browser

37,069

Solution 1

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!

Solution 2

  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>
    

Solution 3

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);

Solution 4

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;
}

Solution 5

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();
    }
}
Share:
37,069
ALR
Author by

ALR

Updated on February 06, 2020

Comments

  • ALR
    ALR over 4 years

    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?