当前位置: 首页 > 知识库问答 >
问题:

StreamCorruptedException:无效类型代码:64

缪宪
2023-03-14

我试图发送消息对象从服务器模块到客户端模块。不幸的是,它抛出java.io.StreamCorruptedExctive:无效类型代码:64错误。有人知道下面的代码有什么问题吗?

客户端来自服务器模块的类

    private boolean needToRun;
    public final Socket socket;
    private OutputStream outputStream;
    private InputStream inputStream;
    private ObjectOutputStream objOut;
    private ObjectInputStream objIn;

    public Client(Socket socket) {
        this.needToRun = true;
        this.socket = socket;
        try {
            this.outputStream = socket.getOutputStream();
            this.inputStream = socket.getInputStream();
            this.objOut = new ObjectOutputStream(outputStream);
            this.objIn = new ObjectInputStream(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        run();
    }

    public void send(Message msg) {
        try {
            objOut.writeObject(msg);
            objOut.flush();
            objOut.reset();
        } catch (Exception ex){
            ex.printStackTrace();
        }

    }

    public void close() {
        needToRun = false;
    }

    public void run() {
        new Thread(() -> {
            while(needToRun) {
                try {
                    int amount = inputStream.available();
                    if (amount != 0) {
                        Message msg = (Message) objIn.readObject();
                        receivedContent(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    public void receivedContent(Message msg) {
        for (Client connection : Server.clients) {
            connection.send(msg);
        }
    }

客户端模块中的Client类看起来相同,但receivedContent看起来如下所示:

    public void receivedContent(Message msg) {
        String errorName = msg.content().trim();
        MainPane.addLabel(errorName);
    }

最后一个Server类,它接受套接字连接:

            while (true) {
                System.out.println("running");
                try {
                    System.out.println("Waiting for client...");
                    Socket socket = serverSocket.accept();
                    clients.add(new Client(socket));

                } catch (Exception e) {
                    if (!serverSocket.isClosed()) {
                        stopServer();
                    }
                    break;
                }
            }

共有1个答案

太叔昊穹
2023-03-14

在客户端类的run方法中

public void run() {
        new Thread(() -> {
            while(needToRun) {
                try {
                    int amount = inputStream.available();
                    if (amount != 0) {
                        Message msg = (Message) objIn.readObject();
                        receivedContent(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

这个代码

int amount = inputStream.available();
if (amount != 0) {
  Message msg = (Message) objIn.readObject();
  receivedContent(msg);
}

这很不可靠。即使inputStream。available()返回1,即1字节可用,然后假设整个对象已准备好读取,因此会得到损坏的数据

假设您知道对象的最大大小,您可以创建一个标准大小的字节数组,并按如下方式读取

byte[] buffer=new byte[8192] //byte array of size 8KB

int length;
while((length=inputStream.read(buffer))>0) //read as much data into this buffer as possible
{
 try(ObjectInputStream objIn=new ObjectInputStream(new ByteArrayInputStream(buffer,0,length)))  //read length bytes of data from this buffer
 {
   Message msg = (Message) objIn.readObject();
   receivedContent(msg);
 }
}

未来的一个建议是将字节数据编码到一个头文件中,可能是这样的

give an byte array of any length encode it as follows

 4 bytes [Integer]         N bytes
------------------------|-------------- 
length of your array    | Your actual data

这样,如果没有足够的数据可用,您可以知道何时等待,还可以将多个对象编码到outputstream中

 类似资料:
  • 问题内容: 我的问题是,当它尝试第二次读取对象时,会引发异常: 我第一次发送完全相同的对象消息;但是,当我第二次尝试执行相同的操作时,则会在上面抛出错误。我是否需要重新初始化readObject()方法?我什至打印出了下面一行所接收到的消息对象,它与第一个可以正常工作的实例完全相同。 Object buf = myInput.readObject(); 我假设附加有一些问题,但是附加确实没有用。我

  • 问题内容: 读取序列化对象时出现错误(java.io.StreamCorruptedException:无效类型代码:00)。这是实现可序列化的类: 这是堆栈跟踪: 有谁知道我如何获得有关该错误的更多信息?还是Java期望哪个对象? 问题答案: 您已经实现了一种递归方法:将实例写入输出流时,它会调用writeObject方法,该方法将写入一个int,然后将该对象写入输出流,再写入一个int,依此类

  • 我的Android Studio工作正常,但在更新插件后,我得到以下错误。我尝试更新JDK并重新安装Android Studio,但仍然面临同样的错误。 这是同步选项卡错误。 这是构建选项卡错误

  • 我正在尝试开发一个Java客户机-服务器应用程序,其中多个客户机可以连接到服务器。我为每个传入的客户机启动一个单独的线程,将客户机套接字传递给该线程,然后打开一对流来维护通信。我得到了这个java。伊奥。StreamCorruptedException-无效的代码类型AC。 根据我的研究,这意味着我使用一个新的ObjectOutputStream来写入现有的ObjectInputStream。然而

  • 我在许多组件中使用了几个大型对象,因此我为每个大型对象创建了一个proptypes文件,如下所示: 其中包含从"prop类型"导入PropType; 我在组件中使用对象,如下所示: 它给我一个警告,Prop类型“PropLargeObject”无效,它必须是一个函数,通常来自React。道具类型。我做错了什么?

  • 问题内容: 大多数Java代码也是语法上有效的Groovy代码。但是,有一些例外使我想到了这个问题: 在Groovy中,Java中哪些构造/功能在语法上无效? 请提供无效的Groovy代码(Groovy 1.6)的Java代码(Java 1.6)的具体示例。 更新: 到目前为止,我们有五个语法上有效的Java代码示例,它们不是有效的Groovy代码: 数组初始化 内部班 是Groovy中的关键字,