2

protobuf と Java を使用してエコー サーバー/クライアントを作成したいだけです。

protobuf-java-2.4.1 と jdk1.7 でテストしました。

以下のようなエコーサーバーコードを書きました

// create server socket and accept for client connection.
// ...
link = servSock.accept();                       
Person person = Person.parseFrom(link.getInputStream()); // blocking position
person.writeTo(link.getOutputStream());

Person.proto に注意する必要はないと思います。

クライアントコードは、ソケット入力ストリームを使用して Person オブジェクトを送信し、エコー Person オブジェクトを受信するだけです。

// socket connect code was omitted.
Person person = Person.newBuilder().setId(1).setName("zotiger").build();
person.writeTo(echoSocket.getOutputStream());
person = Person.parseFrom(echoSocket.getInputStream());

しかし、サーバーとクライアントの両方が実行されている場合、サーバーは parseFrom 関数でブロックされました。

writeDelimitedTo() と parseDelimitedFrom() を使用すれば問題ないことがわかりました。writeTo() および parseFrom() 関数が機能しない理由がわかりません。

サーバーがそこでブロックされたのはなぜですか?

クライアント側から終了信号を送信する必要がありますか?

4

2 に答える 2

5

writeDelimitedTo()/を使用する必要がある理由parseDelimitedFrom()は、そうしないと、プロトコル バッファがソケットから読み取る必要があるデータの量がわからない可能性があるためです。これは問題を引き起こします(もちろん、これを必要としない固定長フィールドのみでメッセージを作成できるためです...しかし、プロトコルバッファは両方のケースに対処する必要があります)

このwriteDelimitedTo()メソッドは、メッセージの長さをOutputStreamメッセージ自体に書き込みます。対応するものparseDelimitedFrom()は長さを読み取り、次にメッセージを読み取ります。

writeTo()とストリームを使用できますpasrseFrom()が、単一のメッセージを読み書きする必要があり、書き込み後にストリームを閉じる場合に限ります。次に、リーダーはメッセージの終わりを示す EOF を取得します (メッセージが 1 つしか含まれていないファイルから読み取る場合も同様です)。

于 2013-05-29T13:55:39.630 に答える
1

独自のクライアント/サーバーを作成しないでください。RPC ソリューション。ここに 1 つがあります...... https://code.google.com/p/protobuf-rpc-pro/には、Java 用の優れた機能がいくつかあります。

于 2013-05-30T19:00:26.153 に答える