简体   繁体   English

如何识别Java套接字中的EOF?

[英]How do I recognize EOF in Java Sockets?

I want to recognize end of data stream in Java Sockets. 我想识别Java套接字中数据流的结尾 When I run the code below, it just stuck and keeps running (it stucks at value 10 ). 当我运行下面的代码时,它只是卡住并继续运行(它卡在值10 )。

I also want the program to download binary files, but the last byte is always distinct, so I don't know how to stop the while (pragmatically). 我还希望该程序下载二进制文件,但是最后一个字节始终是不同的,因此我不知道如何(实用地)停止一会儿

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();

Thanks for any hints. 感谢您的任何提示。

  1. You should use existing libraries for HTTP. 您应该将现有库用于HTTP。 See here . 这里
  2. Your code works as expected. 您的代码按预期工作。 The server doesn't close the connection, and dataBuffer never becomes -1 . 服务器不会关闭连接,并且dataBuffer永远不会变为-1 This happens because connections are kept alive in HTTP 1.1 by default. 发生这种情况是因为默认情况下,连接在HTTP 1.1中保持活动状态。 Use HTTP 1.0, or put Connection: close header in your request. 使用HTTP 1.0,或在您的请求中放入Connection: close标头。

For example: 例如:

out.write("GET "+ path +" HTTP/1.1\r\nHost: "+ host +"\r\nConnection: close\r\n\r\n");
out.flush();

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

out.close();

Actually your code is not correct. 实际上您的代码正确。

In HTTP 1.0 each connection is closed and as a result the client could detect when an input has ended. 在HTTP 1.0中,每个连接都是关闭的,因此客户端可以检测到输入何时结束。

In HTTP 1.1 with persistent connections, the underlying TCP connection remains open, so a client can detect when an input ends with 1 of the following 2 ways: 在具有持久连接的HTTP 1.1中,基础TCP连接保持打开状态,因此客户端可以检测输入何时以以下两种方式之一结束:

1) The HTTP Server puts a Content-Length header indicating the size of the response. 1)HTTP服务器放置一个Content-Length标头,指示响应的大小。 This can be used by the client to understand when the reponse has been fully read. 客户端可以使用它来了解何时已完全读取响应。

2)The response is send in Chunked-Encoding meaning that it comes in chunks prefixed with the size of each chunk. 2)响应以Chunked-Encoding发送,这意味着它以以每个块的大小为前缀的块形式出现。 The client using this information can construct the response from the chunks received by the server. 使用此信息的客户端可以从服务器接收的块中构造响应。

You should be using an HTTP Client library since implementing a generic HTTP client is not trivial (at all I may say). 您应该使用HTTP客户端库,因为实现通用HTTP客户端并非易事(我可能会说)。

To be specific in your code posted you should have followed one of the above approaches. 要在发布的代码中进行具体说明,您应该遵循上述方法之一。

Additionally you should read in lines, since HTTP is a line terminated protocol. 另外,由于HTTP是行终止协议,因此您应该逐行阅读。

Ie something like: 即类似:

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
   }
}

By sending a Connection: close as suggested by khachik, gets the job done (since the closing of the connection helps detect the end of input) but the performance gets worse because for each request you start a new connection. 通过发送Connection: close按照khachik的建议关闭,可以完成工作(因为连接的关闭有助于检测输入的结束),但是性能会变差,因为对于每个请求,您都会启动一个新的连接。

It depends of course on what you are trying to do (if you care or not) 当然,这取决于您要执行的操作(无论您是否在乎)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM