Java - Socket&环

时间:2015-10-15 16:43:16

标签: java sockets http

我正在尝试使用Java将一些HTTP请求连续发送到服务器。

Socket socket = new Socket("ip.address", port);
socket.setKeepAlive(true);  //it does not help
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));

for(int i=1;i<50;i++){

    String data = "some data " + i;
    wr.write("POST " + path + " HTTP/1.0\r\n");
    wr.write("Content-Length: " + data.length() + "\r\n");
    wr.write("Content-Type: application/x-www-form-urlencoded\r\n");
    wr.write("\r\n");
    wr.write(data);
    wr.flush();

}
wr.close();
socket.close();

服务器只接收第一个请求,然后程序通过抛出异常终止

java.net.SocketException: Software caused connection abort: socket write error

所以,我试过这种方式,创建socket&amp;每次关闭循环内部:

for(int i=1;i<50;i++){
    Socket socket = new Socket("ip.address", port);
    BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));

    String data = "some data " + i;
    wr.write("POST " + path + " HTTP/1.0\r\n");
    wr.write("Content-Length: " + data.length() + "\r\n");
    wr.write("Content-Type: application/x-www-form-urlencoded\r\n");
    wr.write("\r\n");
    wr.write(data);
    wr.flush();

    wr.close();
    socket.close();
}

它按照我的预期正常工作。服务器接收所有请求。

问题:

  1. 第二种方法是否正确?如果我打开&amp;每次都关闭,一般不会影响性能吗?或者我如何改进第一种方法?

  2. 还有其他更好的方法来发送HTTP请求吗? (它不必使用套接字)。表现对我们来说非常重要。

3 个答案:

答案 0 :(得分:4)

客户端和服务器必须就连接期望的数据达成一致,即它们都必须遵守应用层协议,在这种情况下是HTTP。

HTTP 1.1 does allow multiple requests per connection,但您的客户端和服务器必须正确协调。例如,如果服务器发送响应,则客户端可能必须在发送下一个请求之前读取它。

您还可以在标头中指定HTTP 1.0,它对每个连接的多个请求没有明确定义的支持。

简而言之,在使用HTTP 1.1协议的现代Web服务器上,只要客户端使用协议定义一致地写入/读取数据,就可以每个请求发送多个请求。

另外,请注意TCP(套接字)keepalive和HTTP keep-alive之间的区别:TCP keepalive管理连接本身,HTTP keep-alive定义跨连接的数据交换的语义。

Java中HTTP客户端的一个好工具是Apache HttpComponents库。该库将处理所有HTTP详细信息,例如标题,连接设置等。

答案 1 :(得分:1)

在第二种方法中,每次都打开一个新连接并将数据发送到服务器。在第一种方法中,您重新使用连接,服务器不期望这样并关闭连接。所以一切都按预期工作。

答案 2 :(得分:1)

你应该阅读 Keep-Alive Header 默认情况下,HTTP 1.1是无状态的,但它具有连接管理选项。它只是添加一个标题并不是那么天真和简单。我建议你使用一些库,例如apache httpclient(参见PoolingClientConnectionManager)

编辑

您应该在POST后读取服务器答案,并在尝试使用keep-alive标头时检查响应标头。