オブジェクト送受信
先ほどのプログラムでは、サーバ・クライアント間の通信をテキストでおこなっていました。 今度は、より複雑なデータを交互に交換できるようにオブジェクトをSerialize で送ってみましょう。 Object の送受信ができれば、様々な情報を構造を保ったまま簡単に送れるはずですよね。
- プログラム: ObjChatServer, ObjChatClient, ObjMessage
まずは接続に関して、サーバプログラムをみてみましょう。
ServerSocket serverSocket = new ServerSocket(portNum);
System.out.println("Server waitting on serverSocket " + serverSocket);
Socket socket = serverSocket.accept(); /* 接続待ち */
System.out.println("Connection established"); /* 接続完了 */
/* ObjectStreamの場合、 out から先に作ってください */
ObjectOutputStream out =
new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in =
new ObjectInputStream(socket.getInputStream());
try {
receiveAndSend(in, out);
} finally {
socket.close();
serverSocket.close();
}
先ほどと大した差はなくて、入出力に ObjectInput/OutputStreamを作っている点だけが違いますね。 注意事項ですが、ObjectInputStream の生成には、相手側の ObjectOutputStream の生成が先に行われる必要があります。out から先に作るか、互違いになるようにしましょう。
送受信部分は、こんな感じ。前回との違いは、
- 一行単位ではなく、オブジェクト単位で読み書きすること
ぐらいです。
while(true) {
ObjMessage recvMsg = (ObjMessage) in.readObject();
System.out.println("Client msg: " + recvMsg);
if(recvMsg.toFinish) break;
System.out.print("Server Input> "); System.out.flush();
String userInput = userIn.nextLine();
ObjMessage sendMsg =
new ObjMessage(userInput,
new Date(),
randomeMaker.nextDouble(),
userInput.equals("exit"));
System.out.println("Server will send msg: " + sendMsg);
out.writeObject(sendMsg);
out.flush(); out.reset();
if(sendMsg.toFinish) break;
}
System.out.println("normal termination");
一点注意事項
があります。Object Serialization は、一度送ったオブジェクトを覚えています。なので、オブジェクトの状態を変えてから再度送信しても、「前に送った奴ね」といって、送信してくれません(前に送ったオブジェクトへの参照を渡す)。ObjectOutputStream#reset()
メソッドを呼ぶと、オブジェクトの状態を忘れてくれます。これで、同じオブジェクトでも再送可能となります。