Socket通信アプリケーション備忘録 No.2
前回からの改善点
前回のエントリーはコチラ。meriyasu-blog.hatenablog.comまずは、単純なミス。
サーバー側でクライアントに対応するための各スレッドにSocketインスタンスを渡すのを
忘れていました。
これでは、スレッド生成しても、クライアントの判別ができないので意味がありません。
MyThreadManager thread = new MyThreadManager(socket);
thread.start();
もちろん、MyThreadManagerは、Threadをextendsします。
このほかにも、startメソッドをオーバーロードし、Socketを受けるstartメソッドを作るという手もあります。
次に通信について。
これまでの考え方では、
ローカルにおいて、座標情報などはすべてリスト(ArrayList, HashMap)に保存し、
リストをリモート側に送信する。
適宜、ファイル化する。
送信・受信形態は、Object Output/Input Streamクラスを利用し、
#writeObject, #readObjectを使用する。
しかし、重大な欠陥が判明...
ObjectOutputStream/ObjectInputStreamは、
通信するデータは直列化されていなければ、ならない。
つまり、シリアライズなどをしなくてはいけません。
ArrayListには、独自クラスのインスタンスなどを格納しており、
その独自クラスも、Serializableインターフェースを実装し、シリアライズUIDも設定していたのですが、
なぜか、うまく動作しません。
デバッグによりわかったことは、
ObjectInputStreamのインスタンス生成時にフリーズしている。
ということです。
つまり、送信するデータなど関係なかったのです。
StackOverFlowなどにもこのようなエラーについて、
OutputStreamを先に定義しろ、
などの記述がありましたが、それは関係ありませんでした。(もしわかる方がおられれば教えてください)
結局、違う通信形態をとることに。
その方法について、入力側は、BufferredInputStreamを用い、
出力側は、PrintWriterを用います。
また、BufferredInputStreamは任意のオブジェクトを扱えるわけではないので、
データは文字列型にしました。
文字列型を受け取ったのち、ローカル上解析メソッドで、要素をリスト形式で返す仕組みにしました。
いろいろ試行錯誤した結果、、、
なんとか完成しました。
あとは、オプション機能を付け加えていくだけです...