4

I am trying to implement a multi threaded java webserver.

Here is my main:

import java.net.*;

public class Main {
    public static void main(String argv[]) throws Exception{

        ServerSocket welcomeSocket = new ServerSocket(6790);
        while(true){
            System.out.println("Waiting...");
            Socket cSock = welcomeSocket.accept();
            System.out.println("Accepted connection : " + cSock);

            Server a = new Server(cSock);
            a.start();


        }
    }
}

here is my thread class:

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


public class Server extends Thread{
    Socket cSock;

    Server(Socket cSock){   //constructor
        this.cSock = cSock;
    }

    public void run(){
        try{
            String request;
            Scanner inFromClient = new Scanner(cSock.getInputStream());
            DataOutputStream outToClient = new DataOutputStream(cSock.getOutputStream());
            request = inFromClient.nextLine();
            System.out.println("Received: "+request);

            //trimming URL to extract file name
            String reqMeth = request.substring(0, 3);
            String reqURL = request.substring(5, (request.lastIndexOf("HTTP/1.1")));
            String reqProto = request.substring(request.indexOf("HTTP/1.1"));
            System.out.println("Request Method:\t" +reqMeth +"\nRequest URL:\t" +reqURL+ "\nRequest Protocol: " +reqProto);

            //passing file name to open
            File localFile = new File(reqURL.trim());
            byte [] mybytearray  = new byte [(int)localFile.length()];
            FileInputStream fis = new FileInputStream(localFile);
            BufferedInputStream bis = new BufferedInputStream(fis);
            bis.read(mybytearray,0,mybytearray.length);

            //sending file to stream
            System.out.println("Sending...");           
            outToClient.write(mybytearray,0,mybytearray.length);
            outToClient.flush();
            outToClient.close();

        }catch(Exception e){
            System.out.println(e);
        }
    }
}

By logic, with each request the server gets, it will create a new thread. Each thread is associated with a particular request. My problem is when i request for a file (eg. index.html), the server gets the request, but the file does not load, the browser keeps on loading.

i figured out that each thread is started but it does not complete.

here is an output:

Waiting...
Accepted connection : Socket[addr=/192.168.0.10,port=58957,localport=6790]
Waiting...
Accepted connection : Socket[addr=/192.168.0.10,port=58958,localport=6790]
Waiting...
Received: GET /html/index.html HTTP/1.1
Request Method: GET
Request URL:    html/index.html 
Request Protocol: HTTP/1.1
Accepted connection : Socket[addr=/192.168.0.10,port=59093,localport=6790]
Waiting...
Received: GET /index.html HTTP/1.1
Request Method: GET
Request URL:    index.html 
Request Protocol: HTTP/1.1

what am i doing wrong? and is there any better way? note that i did only one thread to test request from only one IP, and will build on than once this is solved.

user2114721
  • 45
  • 3
  • 7

3 Answers3

2

You are never writing the HTTP headers.

outToClient.write("HTTP/1.0 200 OK\r\n");
outToClient.write("Connection: Close\r\n");
outToClient.write("\r\n");
outToClient.write(mybytearray,0,mybytearray.length);

If you are going to implement your own server, you should read RFC 2616.

Javier
  • 12,100
  • 5
  • 46
  • 57
1

If you want to connect to the server with a browser, it must return HTTP response with headers. Here is an simple example of HTTP server. Or better look at this answered question.

Community
  • 1
  • 1
Jan Krakora
  • 2,500
  • 3
  • 25
  • 52
0

hope this helps

 import java.io.*;
 import java.net.*;
 import java.nio.file.Files;
 import java.awt.image.BufferedImage;

 import javax.imageio.ImageIO;



 public class TCPServer
 {
 public static void main(String[] argv) throws IOException//IOException
 {
    ServerSocket welcomeSocket = new ServerSocket(9080);

    while(true)
    {
        Socket connectionSocket = welcomeSocket.accept();
        BufferedReader inFromClient = new BufferedReader(new       InputStreamReader(connectionSocket.getInputStream()));
        DataOutputStream outToClient = new     DataOutputStream(connectionSocket.getOutputStream());

        Thread thread = new ClientHandler(connectionSocket, inFromClient,     outToClient);
        thread.start();
    }
}

}

 class ClientHandler extends Thread{
   Socket connectionSocket;
   BufferedReader inFromClient;
   DataOutputStream outToClient;

  public ClientHandler(Socket connectionSocket, BufferedReader inFromClient,     DataOutputStream outToClient) {
    this.connectionSocket = connectionSocket;
    this.inFromClient = inFromClient;
    this.outToClient = outToClient;
  }

   public void run()
   {
      String clientSentence;
      try
      {

          System.out.println("A new client is connected : " + connectionSocket);
          clientSentence = inFromClient.readLine();
          System.out.println("Received: " + clientSentence);
          String[] tokens = clientSentence.split("\\s+");

          if(tokens[1].equals("/index.html") || tokens[1].equals("/"))
          {

              File file = new File(System.getProperty("user.dir")+"/index.html");
              Files.copy(file.toPath(), outToClient);
          }else if(tokens[1].equals("/RealIndex.html"))
          {
              File file = new     File(System.getProperty("user.dir")+"/RealIndex.html");
              Files.copy(file.toPath(), outToClient);
          }
          else if(tokens[1].equals("/hqdefault.jpg"))
          {
              File file = new     File(System.getProperty("user.dir")+"/hqdefault.jpg");
              BufferedImage image = ImageIO.read(file);
              outToClient.writeBytes("HTTP/1.1 200 OK\n\n");
              ImageIO.write(image,"JPG", outToClient);
          }
          else
          {
              File file = new     File(System.getProperty("user.dir")+"/404Error.html");
              Files.copy(file.toPath(), outToClient);
          }

          this.connectionSocket.close();
          this.outToClient.close();
          this.inFromClient.close();
      }catch (IOException e)
      {
          e.printStackTrace();
      }
  }
}