返回无效 GZIP 的套接字 HTTP 请求
Socket HTTP request returning invalid GZIP
我正在自学更多有关 HTTP 请求等的知识,因此我使用 Java 的 HttpURLConnection class 编写了一个简单的 POST 请求,它 returns 压缩数据这很容易解压。我决定进入较低级别并使用套接字发送 HTTP 请求(用于练习)。我在一系列 google 搜索后弄明白了,但有一个问题。当服务器响应压缩数据时,它是无效的。这是一些调试的图像。
http://i.imgur.com/KfAcero.png
“=”分隔线下面的部分是使用HttpURLConnection实例时的响应,而上面的部分是使用套接字时的响应。我不太确定这里发生了什么。底部有效,顶部无效。
HttpParameter 和 header classes 只是存储一个键和值。
public String sendPost(String host, String path, List<HttpParameter> parameters, List<HttpHeader> headers) throws UnknownHostException, IOException {
String data = this.encodeParameters(parameters);
Socket socket = new Socket(host, 80);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer.println("POST " + path + " HTTP/1.1");
for(HttpHeader header : headers) {
writer.println(header.getField() + ": " + header.getValue());
}
writer.println();
writer.println(data);
writer.flush();
StringBuilder contentBuilder = new StringBuilder();
for(String line; (line = reader.readLine()) != null;) {
contentBuilder.append(line + "\n");
}
reader.close();
writer.close();
return contentBuilder.toString();
}
您的问题是您使用 Reader
s 和 Writer
s 来处理非文本内容。
InputStream
和 OutputStream
使用字节; Reader
和 Writer
处理编码文本。如果您尝试将 Reader
和 Writer
用于未编码文本的内容,您将破坏它。
用 Writer 发送请求没问题。
你想做这样的事情:
InputStream in = socket.getInputStream();
// ...
ByteArrayOutputStream contentBuilder = new ByteArrayOutputStream();
byte[] buffer = new byte[32768]; // the size of this doesn't matter too much
int num_read;
while(true) {
num_read = in.read(buffer);
if(num_read < 0)
break;
contentBuilder.write(buffer, 0, num_read);
}
in.close();
writer.close();
return contentBuilder.toByteArray();
并使 sendPost
return 成为一个字节数组。
我正在自学更多有关 HTTP 请求等的知识,因此我使用 Java 的 HttpURLConnection class 编写了一个简单的 POST 请求,它 returns 压缩数据这很容易解压。我决定进入较低级别并使用套接字发送 HTTP 请求(用于练习)。我在一系列 google 搜索后弄明白了,但有一个问题。当服务器响应压缩数据时,它是无效的。这是一些调试的图像。 http://i.imgur.com/KfAcero.png
“=”分隔线下面的部分是使用HttpURLConnection实例时的响应,而上面的部分是使用套接字时的响应。我不太确定这里发生了什么。底部有效,顶部无效。
HttpParameter 和 header classes 只是存储一个键和值。
public String sendPost(String host, String path, List<HttpParameter> parameters, List<HttpHeader> headers) throws UnknownHostException, IOException {
String data = this.encodeParameters(parameters);
Socket socket = new Socket(host, 80);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer.println("POST " + path + " HTTP/1.1");
for(HttpHeader header : headers) {
writer.println(header.getField() + ": " + header.getValue());
}
writer.println();
writer.println(data);
writer.flush();
StringBuilder contentBuilder = new StringBuilder();
for(String line; (line = reader.readLine()) != null;) {
contentBuilder.append(line + "\n");
}
reader.close();
writer.close();
return contentBuilder.toString();
}
您的问题是您使用 Reader
s 和 Writer
s 来处理非文本内容。
InputStream
和 OutputStream
使用字节; Reader
和 Writer
处理编码文本。如果您尝试将 Reader
和 Writer
用于未编码文本的内容,您将破坏它。
用 Writer 发送请求没问题。
你想做这样的事情:
InputStream in = socket.getInputStream();
// ...
ByteArrayOutputStream contentBuilder = new ByteArrayOutputStream();
byte[] buffer = new byte[32768]; // the size of this doesn't matter too much
int num_read;
while(true) {
num_read = in.read(buffer);
if(num_read < 0)
break;
contentBuilder.write(buffer, 0, num_read);
}
in.close();
writer.close();
return contentBuilder.toByteArray();
并使 sendPost
return 成为一个字节数组。