java.io.StreamCorruptedException:无效类型代码:00

java.io.StreamCorruptedException:无效类型代码:00,java,multithreading,sockets,objectoutputstream,Java,Multithreading,Sockets,Objectoutputstream,所以基本上我在写一个客户端-服务器多人游戏。 我有一个SeverCommunicationsRead,如果他收到请求,就会创建一个游戏线程,然后创建一个游戏线程。 当我发送RequestForGame时,会引发java.io.StreamCorruptedException异常:无效类型代码:00 我假设这是因为两个线程都试图读取相同的ObjectInputStream,我对它的工作原理没有太多的了解,我只知道如何使用它。你能帮我了解问题所在以及如何解决吗? 谢谢:) model.addClie

所以基本上我在写一个客户端-服务器多人游戏。 我有一个SeverCommunicationsRead,如果他收到请求,就会创建一个游戏线程,然后创建一个游戏线程。 当我发送RequestForGame时,会引发java.io.StreamCorruptedException异常:无效类型代码:00 我假设这是因为两个线程都试图读取相同的ObjectInputStream,我对它的工作原理没有太多的了解,我只知道如何使用它。你能帮我了解问题所在以及如何解决吗? 谢谢:)

model.addClient方法,但我认为问题不在这里

  public void addClient(String nickname, Socket       clientSocket,ObjectOutputStream stream,ObjectInputStream inStream)
{
    clients.addClient(nickname, clientSocket,stream,inStream);//add to arraylist
//send client list to all clients
    String[] users=this.getAvailableClients();
    ObjectOutputStream[] streams=clients.getOutStreams();
    for(int i=0;i<streams.length;i++)
    {
        try {
            streams[i].writeObject(users);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

}

如果您

  • 在同一套接字上构造新的
    ObjectInputStream
    ObjectOutputStream
    ,而不是在套接字的生命周期内使用相同的套接字
  • 在同一套接字上使用另一种流;或者
  • 使用对象流读取或写入非对象的内容,会导致不同步

如果读取序列化对象的JVM没有正确的对象类/jar文件,也会发生这种情况。这通常会导致
ClassNotFoundException
,但是如果您有不同的jar/class版本,并且版本之间未更改
serialVersionId
,则会生成
streamcorruptedeexception
。(如果存在类名冲突,也可能出现此异常。例如:一个jar包含一个具有相同完整类名的不同类,尽管它们可能还需要相同的
seriversionId


检查客户端是否有正确版本的JAR和类文件。

如果只构造了一次
ObjectInputStream
,然后将它的引用传递给了另一个线程,那么只需将此对象的访问权包含在
synchronized
块中,以确保此时只有一个线程可以访问此对象一段时间

每当您从
ObjectInputStream
读取时,只要在
synchronized
块中访问它(如果它在多个线程之间共享)


示例代码:(对所有出现的
readObject()
执行此操作)


我遇到的另一种可能性是,如果通过添加以下方法为类实现自定义反序列化例程:

private void readObject( ObjectInputStream objectInputStream ) throws IOException
然后必须调用objectInputStream.defaultReadObject(),并在进一步读取输入流之前进行调用,以正确初始化对象

我忽略了这一点,尽管对象返回时没有抛出异常,但下一次读取对象流时却令人困惑地引发了无效类型代码异常


此链接提供了有关流程的进一步信息:。

我也有此例外。发生这种情况是因为我对服务器类和客户端类使用了两个线程。我使用一个线程来发送和接收对象。然后就好了。如果您不熟悉
synchronized
,这是解决问题的简单方法

java.io.StreamCorruptedException:无效类型代码:00

我最近遇到了这个问题,虽然没有像OP那样做。做了一个快速的谷歌搜索,没有找到任何太有用的东西,因为我认为我解决了它,所以我用我的解决方案发表了评论

TLDR:不要让多个线程同时写入同一个输出流(而是轮流)。当客户端尝试读取数据时,将导致问题。解决方案是锁定写入输出


我正在做一些非常类似于OP的事情,制作一个多人(客户机-服务器模式)游戏。我有一个类似OP的线程,可以监听流量。在我的服务器端发生的事情是,服务器上有多个线程同时向客户机的流写入数据(我认为这是不可能的,游戏是半回合基础)。读取传入流量的客户端线程正在引发此异常。为了解决这个问题,我基本上在写入客户端流的部分(服务器端)上设置了一个锁,这样服务器端的每个线程都必须在写入流之前获得锁。

当您调用
model.addClient(昵称、connectionSocket、outToClient、InfoRomClient)时,ServerModelManager在做什么?其中可能有代码正在破坏流。addClient(将用户添加到包含套接字、ObjectOutput和输入流的ClientRepresantative类型的ArrayList中)不读取任何内容。此外,在构造ObjectOutputStreams之后,您应该刷新它们,以确保发送头。这可能是您收到该错误的原因;流标题尚未通过。创建对象后,在客户端和服务器上刷新ObjectOutputStream。我添加了刷新,没有任何更改。您介意在写入对象的位置添加客户端代码吗?我首先在两侧(代理、服务器通信读取)创建ObjectOutputStream。我只构造它一次,然后将它的引用发送给另一个线程。我不使用任何其他类型的流。我想到的唯一一件事是,我试图同时在两个线程中从同一ObjectInputStream读取一个对象。(ServerCommunicationRead,ServerGameThread)这可能是问题所在吗?(从异常的位置来看,我假设是这样的。)@user1420273当然可以,除非您有适当的同步。不,它不能。这种情况会导致ClassNotFoundException。我这样回答是因为我通过安装正确的jar文件成功地修复了问题中的错误。我相信在我的情况下,我有错误的版本(和版本UID没有正确维护),虽然它是一段时间以前现在。。。也可能与类名冲突有关@ejp我将修改我的答案,以表明jar文件的版本-可以自由删除您的否决票,这不会激励您向其他人提供体验的好处!不幸的是,世界不是p
  public class Proxy {
final int PORT = 1337;
String host;
String nickname;
private Socket clientSocket;
private ObjectOutputStream outToServer;
private ObjectInputStream inFromServer;
private ClientModelManager manager;
public Proxy(String nickname,String host,ClientModelManager manager)
{
    this.nickname=nickname;
    this.host=host;
    this.manager=manager;
    this.connect(nickname);
}
public void connect(String nick)
{
    Socket clientSocket;
    try {
        clientSocket = new Socket(host, PORT);
        System.out.println("client socket created");
        outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
        inFromServer=new ObjectInputStream(clientSocket.getInputStream());
        outToServer.flush();
        outToServer.writeObject(nick);
        ClientReceiverThread t=new ClientReceiverThread(inFromServer,manager);
        t.start();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}
public void makeRequest(String user)
{
    try
    {
    outToServer.writeObject(new RequestForGame(user));
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}
public void quit()
{
    try {
        outToServer.writeObject(new String("i want to quit"));
        //clientSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public void sendMove(PlayerMove move)
{
    try {
        outToServer.writeObject(move);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
...
String nickname = null;
synchronized (inFromClient) {
    nickname = (String) inFromClient.readObject();
}
private void readObject( ObjectInputStream objectInputStream ) throws IOException