문제 상황
ObjectInputStream
,ObjectOutputStream
을 통하여 서버(Java program)에서 Object를 write(보내고), 안드로이드 클라이언트에서 read(받는다) 하는 과정에서java.io.StreamCorruptedException: invalid type code: 00
오류가 발생했다. Input과 Output스트림이 1:1이 되어야 한다고 해서 딱 한번만 new 하도록 했고, 동기화 처리도 이것 저것 해봤다. 보내는 형태도 바꿔봤는데 해결을 못했다..
서버 Write 부분 코드
public void WriteChatMsg(ChatMsg obj) {
try {
oos.writeObject(obj.code);
oos.writeObject(obj.UserName);
oos.writeObject(obj.data);
oos.reset();
} catch (IOException e) {
AppendText("oos.writeObject(ob) error");
try {
ois.close();
oos.close();
client_socket.close();
client_socket = null;
ois = null;
oos = null;
} catch (IOException e1) {
e1.printStackTrace();
}
Logout();
}
}
클라이언트(안드로이드) Read 부분 코드
public ChatMsg readChatMsg() {
String code = null, userName = null, data = null;
ChatMsg cm = new ChatMsg("", "", "");
try {
cm.code = (String) networkObj.getOis().readObject();
cm.UserName = (String) networkObj.getOis().readObject();
cm.data = (String) networkObj.getOis().readObject();
if (cm.code.matches("ROOMLIST")) {
cm.list.clear();
cm.list = (ArrayList<String>) networkObj.getOis().readObject();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
logout();
Log.w("From Server with Error", e);
e.printStackTrace();
}
return cm;
}
혹시 안드로이드의 네트워크 프로그래밍, 특히 멀티스레드 환경에서 같은 문제를 겪는 사람이 있다면, new Thread()
말고 안드로이드가 제공하는 비동기 방법인 AsyncTask
를 시도 해보길 바란다.
~(나는 일주일 고생했다,,)~
그리고 ObjectStream 관련해선 이 블로그가 도움이 되었다. (이마저도 100% 이해 할 수는 없었지만,,)
서버 코드는 똑같고,
클라이언트(안드로이드) Read 부분 코드
public ChatMsg readChatMsg() {
ChatMsg cm = new ChatMsg("", "", "");
ReadChatMsgTask readChatMsgTask = new ReadChatMsgTask();
try {
cm = readChatMsgTask.execute().get();
} catch (ExecutionException | InterruptedException e) {
}
return cm;
}
// 비동기처리. 백그라운드에서 동작함
class ReadChatMsgTask extends AsyncTask<String, String, ChatMsg> {
@Override
protected ChatMsg doInBackground(String... strings) {
ChatMsg cm = new ChatMsg("", "", "");
try {
cm.code = (String) networkObj.getOis().readObject();
cm.UserName = (String) networkObj.getOis().readObject();
cm.data = (String) networkObj.getOis().readObject();
if (cm.code.matches("ROOMLIST")) {
cm.list.clear();
cm.list = (ArrayList<String>) networkObj.getOis().readObject();
}
} catch (StreamCorruptedException e) {
Log.w("ServerError", e);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
logout();
Log.w("ServerError", e);
e.printStackTrace();
}
return cm;
}
}
+) 찾아보니 AsyncTask는 언젠가 deprecated 될거라고 한다. 이런..
최근엔 RxJAVA와 Corutine으로 대체하는 중인 듯 하다.