我认为这也可以回答这个问题如何识别 Java 套接字中的 EOF? https://stackoverflow.com/questions/7599742/how-do-i-recognize-eof-in-java-sockets and 我可以向 InputStream 发送什么来表示已达到 EOF? https://stackoverflow.com/questions/6569995/what-can-i-send-to-an-inputstream-to-signify-eof-has-been-reached
我也有类似的问题;我的困境是我有一个客户端/服务器请求响应协议,其中一个请求包含从客户端发送的流clientProps.store()
。相应的serverProps.load()
在服务器端永远不会返回,因为它需要看到“文件结尾”——这在 Java 中意味着客户端必须关闭它的流;导致套接字连接关闭。不想要的结果是,我不仅无法保持套接字打开以进行无限期的请求响应交换,甚至无法保持它打开以供服务器发送回复。
我讨厌 Java 让我这样做,更因为 Properties.load() 的文档说:
此方法返回后,指定的流保持打开状态。
如果它通过查看流关闭来检测文件结尾,则永远不会发生这种情况!不管怎样,现在,我仍然喜欢 Java,因为它允许我使用这个解决方案(如果您对正在流式传输的数据有任何特殊的编码或本地化,则可能没有用):
我在客户端使用了这个:
PrintWriter toServer;
Properties clientProps = new Properties();
// ... code to populate the properties and to
// construct toServer from the socket ...
clientProps.store(toServer, null);
toServer.write('\u001A'); // this is an old-school ASCII end-of-file
toServer.flush();
在服务器端,我扩展了 Reader 来检测 1A 并返回 -1 (以便serverProps.load()
以正常方式了解文件结尾(通过查看从调用返回的 -1read()
), but below也就是说,流和套接字保持打开状态。
BufferedReader fromClient;
Properties serverProps = new Properties();
// ... code to construct fromClient from the socket ...
serverProps.load (new PropReader (fromClient));
/////
private static class PropReader extends Reader {
BufferedReader src;
boolean eof=false;
private PropReader(BufferedReader fromClient) {
super();
src=fromClient;
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int inCount;
if (!eof) {
inCount = src.read(cbuf, off, len);
if (inCount > 0) {
// we read a buffer... look at the end for the EOF that the client used to mark the end of file
if (cbuf[off+inCount-1] == '\u001A') {
--inCount; // don't send eof with the data
eof = true; // next time... we'll return -1
}
}
} else {
inCount = -1;
}
return inCount;
}
@Override
public void close() throws IOException {
src.close();
}