0

I am trying to write a simple http server in java. And here's my code so far:

Server:

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

public class Server
{
    static final int PORT = 8080;
    final String REQUEST_FORMAT = "^GET (.*?) HTTP/1.1$";
    final Socket client;

    public Server(Socket s)
    {
        client = s;
    }

    public void run()
    {
        try
        (Scanner in = new Scanner(new InputStreamReader(client.getInputStream()));
        PrintWriter out = new PrintWriter(client.getOutputStream(),true);)  
        {
            String request = in.findInLine(Pattern.compile(REQUEST_FORMAT));
            System.out.println(request);
            out.write("HTTP/1.1 200 OK");   
        }
        catch(Exception ex)
        {   
            ex.printStackTrace();               
        }
    }

    public static void main(String []args)
    {
        try
        (
        ServerSocket server = new ServerSocket(PORT);
        Socket client = server.accept();
        )
        {
            Server s = new Server(client);
            s.run();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

Client:

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

public class Client
{
    final int PORT = 8080;
    String data = "GET /home/index.html HTTP/1.1";
    public Client()
    {
        try
        (Socket socket = new Socket("127.0.0.1",PORT);
        PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
        Scanner in = new Scanner(new InputStreamReader(socket.getInputStream()));)
        {
            out.print(data);
            String header1 = in.next();
            System.out.println("header="+header1);
            int status = in.nextInt();
            System.out.println("status="+status);
            String message = in.next();
            System.out.println("message="+message); 
        }
        catch(Exception ex)
        {
        }

    }

    public static void main(String []args)
    {
        Client c = new Client();
    }
}

Currently the client just writes a sample request to the server and the server writes a sample response header. But the server seems to be waiting infinitely for client input after reading the request without proceeding to send the response. Please help to resolve this problem.

2 Answers 2

2

If you're implementing an HTTP server you need to implement the HTTP protocol. You aren't doing that. You need to take a long look at RFC 2616, specifically the parts about the content-length header, Connection: close, and chunked transfer encoding, which are here different ways to determine the length of what is being transferred.

You're also not writing lines at any time. The line terminator in HTTP is \r\n, and it doesn't appear anywhere in your code.

There are other problems. Your server will only accept one client and then stop. It needs a loop around the accept code, and it needs to start a new thread to handle each connection.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm not implementing an actual HTTP server. I'm a student and this suppose to be a 'simple' HTTP server - a few hours worth assignment. Thank you for your help anyway.
You still need line terminators, you still need to read lines, and you still need to handle more than one client per server session. You are mistaken if you think you can ignore the HTTP specification when implementing an HTTP server of any kind.
yes I need line terminators. Thank you for pointing that out. That is my mistake. I looked at this link and without reading it fully, came to the conclusion that the request does not have a newline at the end. I have lot more to implement, not only just handling more clients, but I have to implement a thread pool to handle the clients. But I thought I'd do the basic first and see. Thank you very much for the help.
0

Your server blocks at

String request = in.findInLine(Pattern.compile(REQUEST_FORMAT));

The reason is, that the pattern is not found and the stream is also not finished.

Solution A: Close the socket for writing at clientside

out.print(data);
socket.shutdownOutput();

This works only if you don't want to make further writes at clientside.

Solution B:

  1. Client: Write linefeed after data.

    out.print(data);
    out.print("\r\n");
    out.flush();
    
  2. Server: use Scanner.nextLine() and Matcher instead of Scanner.findInLine()

    String line = in.nextLine();
    Matcher matcher = Pattern.compile(REQUEST_FORMAT).matcher(line);
    String request = null;
    if(matcher.find()) {
        //request = line.substring(matcher.start(),matcher.end());
        request = matcher.group();//is similar to the commented line above
    }
    

4 Comments

But isn't it wrong if I write newlines at the end. As far as I know, an HTTP GET request does not have a newline at the end?
@PPGoodMan You are mistaken. Don't make evidence-free guesses.
Have you tried to implement a simple socket server and socket client? Did it work? From there you can make so improvement to make it look like an Http socket server
@EJP yes that's my mistake. I need newline at the end. I looked at the top part of this page and came to the rash conclusion that GET request doesn't have the newline at the end. Thank you for the reply.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.