2

まず、これは宿題の問題です。そうは言っても、私は立ち往生しています。ソケットを介したJavaプロパティのグーグル検索は、多くの無関係なことをもたらします。

ソケットを介して Properties オブジェクトを転送しようとしています。API は、ストリームまたはライター/リーダーで実行できると言っていますが、動作させることができません。手動で行うことができます。つまり、ファイルを 1 行ずつ読み取って 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) を実行する代わりに、1 行ずつ読み込んで props.store(out, null) が機能していることと、データが転送されているように見えることを確認しました。

ロード/ストアについてわからないことがありますか、それともストリーム/ライター/リーダーの問題ですか?

4

1 に答える 1

2

これは、この質問と、Java Sockets で EOF を認識する方法は? EOF に達したことを示すために、InputStreamに何を送信できますか?

同様の問題がありました。私のジレンマは、クライアント/サーバーの要求応答プロトコルがあり、要求の 1 つにクライアント側から送信されたストリームが含まれていたことでしたclientProps.store()serverProps.load()サーバー側の対応するものは、「ファイルの終わり」を確認する必要があるため、返されません。これは、Java では、クライアントがそのストリームを閉じる必要があることを意味します。その結果、ソケット接続が閉じられます。望ましくない結果は、無期限の要求と応答の交換のためにソケットを開いたままにしておくことができなかっただけでなく、サーバーが応答を送信するためにソケットを開いたままにすることさえできなかったということでした。

Properties.load() のドキュメントには次のように書かれているため、Javaがそうするのが嫌いでした。

このメソッドが戻った後、指定されたストリームは開いたままになります。

ストリームが閉じていることを確認してファイルの終わりを検出している場合、これは決して起こりません!! とにかく、今でも 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 に答える