带有序列化对象的 java.io.StreamCorruptedException

标签 java sockets serialization

问题是我得到 java.io.StreamCorruptedException: invalid type code: 9E 每次代码都不同。

我有一个客户端-服务器应用程序,当客户端处于上传状态而服务器处于下载状态时会出现问题。

用户在用户界面上按下按钮,所有选定的文件都会被一一传输到服务器。

这是按钮代码:

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;

}

这一切都适用于这个订单:

  1. 用户点击并发送“iwanttoupload”
  2. 服务器发送正常。 ---- 客户端和服务器端现在处于上述状态。
  3. 客户端发送“startedupload”
  4. 服务器发送“letgo”
  5. 客户端发送 ProtocolFile(序列化)
  6. 服务器发送“sendmemore”,直到他从客户端“iuploadedall”获取

如果用户按一次按钮并等待上传,然后再按一次,这会非常有效。如果用户在上传完成之前按下它,我会收到此异常。

一个快速修复方法是检查用户按下按钮时客户端状态是否为传输状态,否则不执行该操作,但我想修复套接字问题或了解为什么会发生这种情况。我认为当它尝试读取序列化对象时,新上传会发送数据,并且会出现困惑。我实现的状态将避免根据消息进行通信,但消息已发送并且存在问题。

客户端编写代码:

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)

最佳答案

我怀疑问题是在您的按钮代码中您立即写入客户端:

if(_uploadTree.getFiles().getFiles().size() > 0) {
    _client.write("iwanttoupload");
}

如果您遵循在后台线程中处理客户端通信的典型模式,那么您必须只从该线程写入流。该按钮应该只将一个通知排入队列,该通知将在有机会时由该线程处理。

您看到此错误是因为“iwanttoupload”被插入到后台线程正在写入的对象中间,从而损坏了流。

关于带有序列化对象的 java.io.StreamCorruptedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17535298/

相关文章:

java - 为什么 'Do you want to allow this app to make changes to device come up on Windows'

c# - 与 UWP 应用程序的网络连接

c# - 停止线程后,可以用变量取消监听操作吗?

java - 如何序列化原始类型

c# - JSON 将自定义 C# 结构序列化为字符串,而不是对象

java - Eclipse SWT 组为空

java - 对于带有 anchor 的链接,HttpClient 出现 400 错误

java - 每一段时间后执行代码,JAVA

python - 向套接字发送 GET 后忽略/丢弃传入的 HTML

android - 将 Firebase 数据快照反序列化为 Kotlin 数据类