忘れない内にメモメモ。
Protocol Buffersの説明自体はWikipediaさんなどに分かりやすく記述されています。
- Protocol Buffers
本家のProtocol Buffersでは、C++とJavaとPythonに対応しています。
C#から利用する場合は、protobuf-netを利用します。
- protobuf
- protobuf-net
やり方としては
となります。
で、まず最初にprotoファイルを作成する必要があります。
protoファイルの書き方については、以下に記載があります。
- Language Guide
今回は以下のようなシンプルなprotoファイルを作成
名前はtest.protoとしました。
message HelloWorld { required string message = 1; required int32 age = 2; required bytes bytearray = 3; }
見たまんまですが、文字列フィールド、数値フィールド、バイト配列フィールドとなります。
これをprotobufが用意してくれているコンパイラに食わせます。
これによって、JavaとCSのソースファイルが出力されます。
ただし、C#の場合は、通常のprotocを利用するのではなく、protobuf-netのprotogenを利用します。
まず、Javaソースファイルを出力.
コマンドラインで以下のようにします。
protoc --java_out=出力ディレクトリ protoファイル
次に、C#ソースファイルを出力.
コマンドラインで以下のようにします。
protogen -i:protoファイル -o:csファイル名
これで準備完了です。出力されたソースファイルを適切な場所に配置します。
後はJava側とC#側に必要なライブラリを参照設定して利用します。
JavaでMaven利用している場合は以下の依存関係をpom.xmlに記述。
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>2.5.0</version> </dependency>
C#側では、nuget利用してprotobuf-netをインストールしたりすると楽です。
protobuf-netをmsiインストーラとかでインストールしている場合は
インストールディレクトリの下にdllファイルが存在しますので、それを参照設定してもオッケイです。
で、後は処理を記述すればオッケイです。
今回はJava側がサーバでC#側がクライアントと仮想定して
ソケットで通信してデータをやり取りしてます。
まずは、java側。
たいした事してませんが、一応サンプルです。
サーバー起動して後は待ってるだけです。
package protobufsample; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import protobufsample.Test.HelloWorld; public class App { public static void main(String[] args) throws Exception { App me = new App(); me.start(); } public void start() throws IOException { try (ServerSocket server = new ServerSocket(9999)) { System.out.println("server started..."); try (Socket client = server.accept()) { System.out.println("got client connection..."); try (InputStream is = client.getInputStream()) { while (is.available() == 0) { // // 利用可能になるまで待機 // } byte[] bytes = new byte[is.available()]; is.read(bytes); HelloWorld obj = HelloWorld.parseFrom(bytes); System.out.printf("%s, %d, %s\n", obj.getMessage(), obj.getAge(), obj.getBytearray().toString()); } } } } }
次はC#側。
こちらはデータを作成して、サーバーに送信しています。
namespace ProtoBufTest { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; using ProtoBuf; class Program { static void Main(string[] args) { var obj = new test.HelloWorld(); obj.message = "hello protobuf"; obj.age = 99; obj.bytearray = new byte[] { 20, 21, 22 }; using (var client = new TcpClient()) { client.Connect(new IPEndPoint(IPAddress.Loopback, 9999)); using (var stream = client.GetStream()) { Serializer.Serialize<test.HelloWorld>(stream, obj); } } Console.WriteLine("data sended...."); Console.ReadLine(); } } }
余談ですが、Java側でデータを作成する場合は以下のようにします。
public static void main(String[] args) throws Exception { byte[] bytes = new byte[3]; bytes[0] = 20; bytes[1] = 21; bytes[2] = 22; HelloWorld hw = HelloWorld .newBuilder() .setMessage("Hello World Protobuf") .setAge(99) .setBytearray(ByteString.copyFrom(bytes)) .build(); }
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場