読者です 読者をやめる 読者になる 読者になる

あさちゅんのゲームブログ

UnityやSiv3Dに関するゲーム開発メモを残していきます

Siv3DのTCP通信で文字列を扱う

スタンドアローンなゲームもいいですが、やっぱりプログラマーなら一度はサーバを作って通信ゲームを作ってみたいですよね。そのためにはSiv3D単体ではなく、RubyPythonといったサーバサイドとTCP通信などで連携する必要があります。

スクリプト言語は簡単にTCP通信が可能ですが、Siv3Dでは一筋縄ではいきません。そこで、今回はSiv3DのTCP通信を使って文字列を送受信する方法を紹介したいと思います。

ちなみに、面倒という方はも下記のモジュールを使っていただければ、すぐに文字列を送受信できるようになります。

そもそも、なぜ難しい?

Siv3Dには簡単かつシンプルなTCP通信のサンプルがあります。

しかし、なぜ同じように文字列が送受信できないかというと、Siv3Dが一発で送受信可能なのはTrivially Copyableな型に限られているからです。

これは簡単に言うと、メモリをそのままコピーしても同じ値になる型のことを指します。Siv3Dで文字列を扱うString型はwchar型の集合であり、String型だけでなく、それが指し示すwchar型の集合も送らなければ意味がないからです。

なので、今回はStringクラスを送るのではなく、このwchar型の集合を送受信する方法を紹介します。

文字列を送信する

String型をwchar型に分解して送りたいところですが、Ruby等ではString型が保持するワイド文字列のままだと扱いにくいので、ToUTF8関数でマルチバイト文字列にし、char型の集合を送信します。

TCPClient::send関数の第一引数に文字列の先頭アドレス、第二引数にいくつ送るかを指定します。

この時、string::length()を指定したくなりますが、型の大きさまで考慮する必要があるので、要素の大きさ、つまりchar型のサイズをかけておきます。

(char型のサイズは1なので意味はないですが、、、)

文字列を受信する

受信する方はひと手間かける必要があります。

マルチバイト文字列は1文字が必ずしも、実際の1文字とは限りません。なので、日本語なども扱う場合には、1文字が1バイトの文字を目印にして、文字の途中で読み込みを終了しないようにします。

今回はよく使う1行を読み込む、つまり改行文字 '\n' を目印にします。

まず、String型ではなくマルチバイト文字列が扱えるstd::string型を用意します。そして、char型を1つずつ読み取り、目印の改行文字が来るまでstd::stringに貯めます。改行文字が来たら、FromUTF8関数を用いてワイド文字列に変換します。

まとめ

序盤に難しそうな話があったにも関わらず、とっても簡単に文字列の送受信が出来たと思います。

誰でも簡単にネットが使える時代ですから、これを機にネットワークを利用したゲームを作ってみるのもいいんじゃないでしょうか?

おまけ

コピペで動くSiv3Dと、コピペで動くRubyのエコーサーバを置いておきます。開発環境さえあれば、この2つで通信ができます。

使用したソフト
Windows 10
Siv3D August 2016
Ruby 2.3.1