問題は、 java.io.StreamCorruptedException: invalid type code: 9E 毎回コードが異なることです。
私が持っているのはクライアントサーバーアプリケーションであり、クライアントがアップロード状態にあり、サーバーがダウンロード状態にあるときに問題が発生します。
ユーザーが UI からボタンを押すと、選択したすべてのファイルが 1 つずつサーバーに転送されます。
ボタンのコードは次のとおりです。
try {
_client.setProtocolFiles(_uploadTree.getFiles());
if(_uploadTree.getFiles().getFiles().size() > 0) {
_client.write("iwanttoupload");
} else {
CustomDialog.showInfoDialog("Πρέπει να επιλέξετε αρχεία", "Προσοχή");
}
} catch (Exception e) {
e.printStackTrace();
}
クライアントのアップロード状態は次のとおりです。
@Override
public void interact(Object theInput) throws Exception {
if(theInput.equals("uploadedsuccessfully")) {
System.out.println("uploadedsuccessfully");
_client.setState(new TranferState(_client));
} else if(theInput.equals("letsgo") || theInput.equals("sendmemore")) {
if(_fileToBeSent < _client.getProtocolFiles().getFiles().size())
sendFiles(theInput);
else
_client.write("iuploadedall");
_fileToBeSent++;
} else if(theInput.equals("idontunderstandyou")) {
_client.setState(new TranferState(_client));
}
}
private void sendFiles(Object theInput) throws Exception {
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(_client.getProtocolFiles().getFiles().get(_fileToBeSent).getPath()));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
_client.getProtocolFiles().getFiles().get(_fileToBeSent).setFile(buffer);
try {
_client.write(_client.getProtocolFiles().getFiles().get(_fileToBeSent));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch(IOException ex) {
System.out.println(ex.getMessage());
_fileToBeSent++;
interact(theInput);
}
}
これはサーバーのダウンロード状態です:
@Override
public String reply(Object theInput) {
String outPut = "";
if(theInput.equals("iuploadedall")) {
outPut = "uploadedsuccessfully";
_connection.setConnectionState(new TranferState(_connection));
} else if (theInput.equals("startedupload")) {
outPut = "letsgo";
} else if(theInput instanceof ProtocolFile) {
try {
System.out.println(theInput.toString());
ProtocolFile file = (ProtocolFile)theInput;
FileOutputStream fos = new FileOutputStream("C:\\" + file.getName());
fos.write(file.getFile());
fos.close();
outPut = "sendmemore";
} catch (IOException e) {
e.printStackTrace();
}
} else {
outPut="idontunderstandyou";
_connection.setConnectionState(new TranferState(_connection));
}
return outPut;
}
これはすべて、次の順序でうまく機能します。
- ユーザーが「iwanttoupload」をクリックして送信
- サーバーはOKを送信します。---- クライアントとサーバーは上記の状態になりました。
- クライアントは「startupload」を送信します
- サーバーは「letsgo」を送信します
- クライアント送信 ProtocolFile (シリアル化)
- サーバーは、クライアントから「iuploadedall」を取得するまで「sendmemore」を送信します
これは、ユーザーがボタンを 1 回押して、アップロードが待機するのを待ってからもう一度押すとうまく機能します。アップロードが完了する前にユーザーがそれを押すと、この例外が発生します。
簡単な修正の 1 つは、クライアントの状態が転送状態の場合にユーザーがボタンを押したときに確認することです。それ以外の場合はアクションを実行しませんが、ソケットの問題を修正するか、なぜこれが起こっているのかを理解したいと考えています。シリアル化されたオブジェクトを読み込もうとすると、新しいアップロードがデータを送信し、混乱があると思います。私の実装された状態は、メッセージに従って通信を回避しますが、メッセージは送信され、問題があります。
クライアント書き込みコード:
public void write(Object credentials) throws Exception {
if (credentials != null && _socket !=null && !_socket.isClosed()) {
_oos.writeObject(credentials);
} else {
connect();
_oos.writeObject(_credentials);
_oos.flush();
_oos.writeObject(credentials);
}
_oos.flush();
}
サーバー読み取りコード:
while ((input = ois.readObject()) != null) {
if (_connectionState.getClass().equals(ClosedState.class)) {
break;
}
oos.writeObject(Protocol.processInput(input, _connectionState));
oos.flush();
}
例外はここにあります:
while ((input = ois.readObject()) != null)