多线程http服务器从客户端浏览器获取GET和POST

时间:2012-03-16 02:08:15

标签: java networking network-programming network-protocols

我正在尝试运行一个简单的多线程服务器来获取URL,并且允许浏览器将文件上传到服务器(GET和POST)它使用GET获取网页我遇到了POST问题,这是我的WebServer我正在使用上传工作。注意:HttpRequest是另一个处理线程的类

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


public class WebServer
{

    public WebServer(int port)
    {

        System.out.println("starting web server on port " + port);

        ServerSocket serverSocket = null;

        try
        {
            //create the server
            serverSocket = new ServerSocket(port);
        }catch(IOException ex)
        {
            System.out.println("could not open port " + port);
            System.exit(1);
        }

        //loop indefinitely
        while(true)
        {
            try
            {
                Socket connection = null;
                connection = serverSocket.accept();
                //accept the connection

                //create a new thread, start it and return to the waiting state
                HttpRequest request = new HttpRequest(connection);
                Thread t = new Thread(request);
                t.start();

            }catch(IOException ex)
            {
                //fail if an error occurs
                System.out.println("problem accepting connection");
                System.exit(1);
            }
        }

    }

    public static void main(String[] args)
    {

        //simple validation for the port number
        if(args.length != 1)
        {
            System.out.println("please specify a port");
            System.exit(1);
        }

        int port = -1;
        try
        {
            port = Integer.parseInt(args[0]);

        }catch(NumberFormatException ex)
        {
            System.out.println("invalid port number");
            System.exit(1);
        }

        WebServer server = new WebServer (port);

    }

}

这里是Http实现runnable

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

public class HttpRequest implements Runnable
{

    private DataInputStream input = null;
    private Socket connection;

    private static DataOutputStream output = null;

    public HttpRequest(Socket connection)
    {
        this.connection = connection;
    }

    //required method so this can be used as a thread
    public void run()
    {
        try
        {
            //try and get the streams
            input = new DataInputStream(connection.getInputStream());
            output = new DataOutputStream(connection.getOutputStream());
        }
        catch(IOException ex)
        {
            System.out.println("could not get input/output streams from connection: " + connection.toString());
            return;
        }

        try
        {
            StringBuilder response = new StringBuilder("");

            String request = input.readLine();

            System.out.println("request: " + request);

            String[] requestArray = request.split(" ");

            //read off and ignore the rest of the input
            //added so this can be tested with real browsers
            while(input.available() != 0)
            {
                input.read();
            }

            if (requestArray.length != 3)
            {
                //request should be of the format GET /index.html HTTP/1.1, die if a bad request comes in
                System.out.println("bad request: " + request);
                return;
            }else
            {
                //requested file should be the second entry, remove the leading '/'
                File requestedFile = new File(requestArray[1].substring(1));

                System.out.println("requested file: " + requestedFile);

                //check the requested file exists
                if(requestedFile.exists())
                {
                    System.out.println("file found, sending response");

                    DataInputStream fileInput = new DataInputStream(new FileInputStream(requestedFile));

                    //output HTTP header, must be followed by two new lines
                    response.append("HTTP/1.1 200 OK\n\n");

                    String line = fileInput.readLine();

                    while(line != null)
                    {
                        response.append(line);
                        line = fileInput.readLine();
                    }

                    fileInput.close();

                    output.writeBytes(response.toString());
                    output.flush();
                    output.close();

                    Logger.writeToLog("Request: " + request + "\r\nResponse: " + response.toString());

                }
                else
                {
                    System.out.println("file not found, sending 404");

                    response.append("HTTP/1.1 404 Not Found\n\n");
                    output.writeBytes(response.toString());

                    output.flush();
                    output.close();
                }

            }

        }
        catch(IOException ex)
        {
            System.out.println("cannot read request from: " + connection.toString() + ex.toString());
            return;
        }
        catch(NullPointerException ex)
        {
            System.out.println("bad request: " + connection.toString());
            return;
        }

        try
        {
            input.close();
            output.close();

            connection.close();
        }
        catch(IOException ex)
        {
            System.out.println("Can't close connection: " + connection.toString());
            return;
        }
    }

}

1 个答案:

答案 0 :(得分:2)

您的问题是您的HttpRequest类没有正确实现HTTP协议。对于初学者,您假设所有请求都是GET请求,而您忽略了请求行后面的标题行。

您需要做的是彻底阅读HTTP 1.1规范......并重写您的代码,以便它读取和处理请求,并根据规范应该如何完成生成响应。

或者,不要浪费时间重新发明轮子(可能不正确)。使用现有的Web容器框架或现有的HTTP协议堆栈,例如Apache HttpComponents。