1

我正在构建自己的 http 客户端。我让它工作,但试图清理代码并使其更有效率。没有语法错误或运行时错误。但是由于某种原因,当我运行程序时,它在尝试发送第一个 GET 请求时挂起,并最终超时并显示以下消息:

408 Request Time-out:服务器等待来自客户端的HTTP请求超时。

这是我的整个班级。

public class MyHttpClient {

//Variables
String host;//Host name
int port; //port number to connect to
String path; //Path of resource being requested
String method; //Type of method (GET or POST)
String blankLine = "\r\n"; //Carriage return
String line; //Hold Strings returned from server
int status; //Hold the response code
String description; //Hold the response code description
String name; //Hold name of NameValuePair
String value;//Hold value of NameValuePair
String body; //Hold the body of the response
String queryString;//Hold the query string of the request
int length; //Hold the content length being sent to server

public MyHttpResponse execute(MyHttpRequest request) throws IOException {

    //Create the Http response object
    MyHttpResponse response = new MyHttpResponse();
    //Establish a connection to the server
    //Get host and port
    host = request.getHost();
    port = request.getPort();

    Socket connectionSocket = new Socket(host,port);

    //Create I/O streams
    //input
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
    //output
    DataOutputStream outToServer = new DataOutputStream(connectionSocket.getOutputStream());

    //Get the file path
    path = request.getPath();

    //Get the type of method
    method = request.getMethod();

    //Handle GET request
    if(method.equalsIgnoreCase("GET")){
        System.out.println(host + " " + port + " " + path);
        //REQUEST
        //Construct the GET request and send to server via output stream
        outToServer.writeBytes("GET " + path + " HTTP/1.0" + "\r\n"); //Request line
        outToServer.writeBytes("Host: localhost.com" + "\r\n"); //GET request headers
        outToServer.flush();

        //RESPONSE
        //Read in the response from the server
        line = inFromServer.readLine();

        //Check the status code & assign to response - if not 200 throw error!
        status = Integer.parseInt(line.substring(9,12));
        response.setStatus(status);

        //Get the status code description & assign to response - if 200 should be OK.
        description = line.substring(13);
        response.setDescription(description);

        //Get the response headers
        do{
            line = inFromServer.readLine();
            if(line != null){
                name = line.substring(0, line.indexOf(":"));//Key
                value = line.substring(line.indexOf(":"));//Value
                response.addHeader(name, value);//Add to response object
            }
        }while(line != null && line.length() == 0);
        //Do the above loop until a blank line is reached. This indicates
        //the end of the headers and the start of the content.

        //Get the body (content) - After a blank line
        StringBuilder sb = new StringBuilder();
        do{
            line = inFromServer.readLine();
            if(line != null){
                sb.append(line).append("\n");
            }
        }while(line != null);
        //Loop until there is no more lines left.

        //Convert the data to a string and set it as the response object's body.
        body = sb.toString();
        response.setBody(body);
    }

    //Handle POST request
    if(method.equalsIgnoreCase("POST")){
        //REQUEST
        //Get the query string from request and it's length
        queryString = request.getQueryString();
        length = queryString.length();

        //Construct the POST request and send to the server via the output stream
        outToServer.writeBytes("POST: " + path + " HTTP/1.0" + blankLine);//Request line
        outToServer.writeBytes("Host: localhost.com" + blankLine);//Header lines
        outToServer.writeBytes("Content-Type: application/x-www-form-urlencoded" + blankLine);
        outToServer.writeBytes("Content-Length: " + String.valueOf(length) + blankLine);
        outToServer.writeBytes(blankLine); //blank line to indicate end of headers and start of body
        outToServer.writeBytes(queryString);//query string "hidden" in POST request body, in GET this query string is "visible",added to the url.
        outToServer.flush();

        //RESPONSE
        //read the response and get the status code and assign to the response
        line = inFromServer.readLine();
        status = Integer.parseInt(line.substring(9,12));
        response.setStatus(status);

        //get the response status description and assign to response
        description = line.substring(13);
        response.setDescription(description);

        //read the response headers
        do{
            line = inFromServer.readLine();
            if(line != null){
                name = line.substring(0, line.indexOf(":"));
                value = line.substring(line.indexOf(":"));
                response.addHeader(name, value);
            }
        }while(line != null && line.length() == 0);
        //(above)Same as GET - loop through the headers until blank line reached
        //indicating the start of the response body.

        //read the response body (content)
        StringBuilder sb = new StringBuilder();
        do{
            line = inFromServer.readLine();
            if(line != null){
                sb.append(line).append("\n");
            }
        }while(line != null && line.length() == 0);
        //(above)Loop through until there is a blank line - end of the content

        //Convert to string and assign as response body.
        body = sb.toString();
        response.setBody(body);

    }
    //Close the connection to the server
    connectionSocket.close();

    //Return the response
    return response; 
}

}//课程结束

任何人都可以看到可能导致它的原因吗?我从原始工作代码中改变的一件事是输出流来自:

s.getOutputStream().write(("GET " + path + " HTTP/1.0\r\n").getBytes("ASCII"));

使用一个DataOutputStream

outToServer.writeBytes("GET " + path + " HTTP/1.0" + "\r\n");

4

1 回答 1

2

当我发布问题时,我意识到我的错误。我忘了在 GET 请求标头后放一个空行。

这修复了它:

//Construct the GET request and send to server via output stream
outToServer.writeBytes("GET " + path + " HTTP/1.0" + "\r\n"); //Request line
outToServer.writeBytes("Host: localhost.com" + "\r\n"); //GET request headers
outToServer.writeBytes(blankLine);
outToServer.flush();
于 2013-01-30T00:47:51.840 回答