有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

http如何识别Javasocket中的EOF?

我想识别Javasocket中数据流的结尾。当我运行下面的代码时,它只是卡住并继续运行(它在值10处卡住)

我也想让程序下载二进制文件,但最后一个字节总是不同的,所以我不知道如何在时停止(实际上)

String host = "example.com";
String path = "/";
Socket connection = new Socket(host, 80);

PrintWriter out = new PrintWriter(connection.getOutputStream());
  out.write("GET "+ path +" HTTP/1.1\r\nHost: "+ host +"\r\n\r\n");
out.flush();

int dataBuffer;
while ((dataBuffer = connection.getInputStream().read()) != -1)
  System.out.println(dataBuffer);

out.close();

谢谢你的提示


共 (1) 个答案

  1. # 1 楼答案

    实际上你的代码是不正确的

    在HTTP 1.0中,每个连接都是关闭的,因此客户端可以检测输入何时结束

    在具有持久连接的HTTP 1.1中,底层TCP连接保持打开状态,因此客户端可以通过以下两种方式之一检测输入何时结束:

    1)HTTP服务器放置一个Content-Length头,指示响应的大小。这可以被客户用来理解响应何时被完全读取

    2)响应以Chunked-Encoding的形式发送,这意味着它以块的形式出现,前缀是每个块的大小。使用此信息的客户端可以根据服务器接收的数据块构造响应

    您应该使用HTTP客户机库,因为实现通用HTTP客户机并不简单(我可以这么说)

    具体来说,你应该遵循上述方法之一

    此外,由于HTTP是一种以行终止的协议,所以应该以行为单位进行读取

    例如:

    BufferedReader in =new BufferedReader(new InputStreamReader( Connection.getInputStream() ) );
    String s=null;
    while ( (s=in.readLine()) != null)  {
    //Read HTTP header
         if (s.isEmpty()) break;//No more headers
       }
    }
    

    按照khachik的建议,通过发送Connection: close,可以完成任务(因为关闭连接有助于检测输入的结束),但性能会变得更差,因为对于每个请求,都会启动一个新的连接

    这当然取决于你想做什么(如果你在乎或不在乎)