2

首先,这是一个家庭作业问题。话虽如此,我被困住了。通过 Sockets 搜索 Java 属性会导致很多不相关的事情。

我正在尝试通过套接字传输属性对象。API 说它可以用 Stream 或 Writer/Reader 完成,但我无法让它工作。我可以手动完成,也就是说,如果我逐行读取文件并通过 PrintWriter 传递它。

在客户端,我大致有:

socket = new Socket(host, port);
outStream = socket.getOutputStream();
out = new PrintWriter(outStream, true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
reader = new BufferedReader(new FileReader(file));
...
props.load(reader);
props.store(out, null);

在服务器端,接收位如下所示:

out = new PrintWriter(sock.getOutputStream(), true);
inStream = sock.getInputStream();
in = new BufferedReader( new InputStreamReader(inStream));
...
props.load(in); // hangs
// doesn't get to code here...

在这种情况下,它挂在 props.load(in) 处。我没有执行 props.load(in),而是逐行读取它以确保 props.store(out, null) 正常工作,并且数据看起来像是在传输。

有什么关于加载/存储的东西我不明白,还是流/写入器/读取器有问题?

4

1 回答 1

2

我认为这将回答这个问题以及如何识别 Java 套接字中的 EOF?以及我可以发送什么到 InputStream 以表示已达到 EOF?

我有类似的问题;我的困境是我有一个客户端/服务器请求-响应协议,其中一个请求包括从客户端发送的流,使用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()以正常方式了解文件结尾(通过查看从调用返回的 -1 read()),但在此之下,流和插座保持打开状态。

    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();
    }
于 2013-02-07T19:22:41.560 回答