我正在建立自己的http客户端。我得到了它的工作,但试图清理代码,使其更有效。没有语法错误或运行时错误。但是由于某些原因,当我运行该程序时,它会在尝试发送第一个GET请求时挂起,并以此消息结束超时:
408请求超时:服务器超时等待来自客户端的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;
}
} // END OF CLASS
任何人都可以看到可能导致它的原因吗?我从原始工作代码改变的一件事是来自:
的输出流 s.getOutputStream().write(("GET " + path + " HTTP/1.0\r\n").getBytes("ASCII"));
使用DataOutputStream
outToServer.writeBytes("GET " + path + " HTTP/1.0" + "\r\n");
答案 0 :(得分: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();