多线程的Java Web服务器

时间:2013-03-06 13:20:02

标签: java multithreading webserver

我正在尝试实现一个多线程的java webserver。

这是我的主要内容:

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


        }
    }
}

这是我的主题类:

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

按逻辑,服务器获取每个请求,它将创建一个新线程。每个线程都与特定请求相关联。 我的问题是当我请求文件(例如index.html)时,服务器获取请求,但文件未加载,浏览器继续加载。

我发现每个线程都已启动但未完成。

这是一个输出:

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
我在做错了什么?有没有更好的方法?请注意,我只做了一个线程来测试来自一个IP的请求,并且将在不再一次构建时解决这个问题。

3 个答案:

答案 0 :(得分:2)

您永远不会编写HTTP标头。

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

如果您要实现自己的服务器,请阅读RFC 2616

答案 1 :(得分:1)

如果要使用浏览器连接到服务器,则必须返回带有标头的HTTP响应。 Here是HTTP服务器的一个简单示例。或者更好地看看this回答的问题。

答案 2 :(得分:0)

希望这会有所帮助

import java.util.ArrayList;

public class TaskExecutor implements Runnable {

    private ArrayList<String> arr;

    public TaskExecutor(ArrayList<String> arr) {
        this.arr = arr;
    }

    @Override
    public void run() {

            String task;
            while (arr.size() != 0 &&  (task = arr.remove(0))!=null) {
                System.out.println(Thread.currentThread().getName() + " : [" + task + "] has been executed");
            }
    }
}

}

import java.util.ArrayList;

public class Main {

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

        ArrayList<String> task_queue = new ArrayList<>();

        for(int i = 0; i < 10000; i++) {
            task_queue.add("Task" + i);
        }

        Thread t1 = new Thread(new TaskExecutor(task_queue));
        Thread t2 = new Thread(new TaskExecutor(task_queue));
        Thread t3 = new Thread(new TaskExecutor(task_queue));
        Thread t4 = new Thread(new TaskExecutor(task_queue));
        Thread t5 = new Thread(new TaskExecutor(task_queue));

        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
        t4.setName("t4");
        t5.setName("t5");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();

        System.out.println();

        while(t1.isAlive() || t2.isAlive() || t3.isAlive() || t4.isAlive() || t5.isAlive()) {
        }

        System.out.println("waiting...");
        Thread.currentThread().sleep(2000);
        System.out.println("finished");
        System.out.println("Number of Tasks left : " + task_queue.size());
    }

}