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

通信対戦

目標達成。2つのマシンからひとつの国を操作できるようになった。
とは言え、現状全く同期できてない上に、サーバー側とクライアント側で指示がごちゃごちゃになってしまっている。工場にユニット作成指示出したら、クライアント側はローカルの作成指示とサーバーから来た作成指示で2重にユニットが作成されてしまう有様。
まだまだまだまだ先は長い。


ネットワークもマルチスレッドもほとんど手を出したことが無い分野なので、どうでもいい部分でかなり時間を食った感が。
以下ここ数日の作業記録。

・まずはポータブルなネットワークライブラリの模索。と言ってもwinsockとPOSIX Socketに対応してればいいので薄いラッパでいい。最初はSDL_netを使おうとしてたけど、acceptがブロックしないようになってるとか、生のAPIからいくつか改造が加えられてるのが気に食わなくて止めた。結局こちらのgimite::socketを使わせていただいた。
http://gimite.ddo.jp/gimite/

・んで、送受信の部分で散々詰まる。

・2回以上連続でsendするとか、recvで溜まってるデータ分以上のデータを受信しようとしたら、その時点でそのソケットは無効になってしまうようだ?(不確定。というかこれが分かるまでに2日以上かかったような。ソケットの解説サイトにもこれ系の情報が見当たらない)

・なので通信が必要になるたびにソケットを新規に作らないといけない…のかと思ったけど、AoCとかをやってるところをTCPViewで見てもそのような様子は無い。1回作ったソケットを使い続けてるっぽい?というかその方が合理的な気がするのでできればそうしたい。

・2回以上連続でsendせず、溜まってる分以上のデータをrecvしなければ、一回作ったソケットをずっと使い続けられるようだ。バイナリデータなら先頭にデータサイズをつけてその分だけしか受信しない、テキストデータなら終端文字を決めてその文字を受信したとき受信を終える、で、解決?あと当然サーバー側も1回acceptで作ったソケットをずっと使い続けないといけない。

・というわけで、クライアントはサーバーとの通信用に1つ、サーバー側は待ち受け用(accept用)に1つと、acceptした後のクライアントとの通信用に1クライアントにつき1つのスレッドを作るように。

・マルチスレッドなので排他制御もそれなりに。幸い処理が被る可能性がある部分は少ないので楽ちん。そういえばmutexを2重にロックしたらフリーズするらしき。

・やりとりするデータは全部テキストに変換してから送受信するようにした。テキストだとデータ量増える上に、データを文字列に変換したり文字列から復元したりするのに余分に処理が食われるけど、エラーチェックがやりやすくなるので。最終的にはバイナリデータでやりとりするようにする予定。