English 中文(简体)
java.io.StreamCorruptedException:无效类型代码:00
原标题:java.io.StreamCorruptedException: invalid type code: 00

So basically im writing a client-server multiplayer game. I have a SeverCommunicationThread that creates a gameThread if he receives a RequestForGame creates a gameThread. When i send a RequestForGame exception is thrown java.io.StreamCorruptedException: invalid type code: 00 I assume it s because both threads try to read the same ObjectInputStream, I don t have much understanding about how it works, i just know how to use it. Could you help me understand what s the problem and how to fix it? Thanks :)

public class ServerCommunicationThread extends Thread{
private Socket connectionSocket;
private ObjectInputStream inFromClient;
private ObjectOutputStream outToClient;
private String nickname;
private ServerModelManager model;


public ServerCommunicationThread(Socket connectionSocket,
        ServerModelManager model) throws IOException {
    this.connectionSocket = connectionSocket;
    inFromClient = new ObjectInputStream(connectionSocket.getInputStream());
    outToClient = new ObjectOutputStream(connectionSocket.getOutputStream());
    this.model = model;
    start();

}

public void run() {
    try {
        String nickname = (String) inFromClient.readObject();
        if (model.exists(nickname)){
            System.out.println(nickname + " already exists");
            outToClient.writeObject(new MessageForClient("Please choose another nickname"));
        }
        else
        {
            System.out.println(nickname + " connected, adding to list");
            model.addClient(nickname, connectionSocket,outToClient,inFromClient);
            this.nickname=nickname;
        }
        while(true){
            Object o= inFromClient.readObject();//StreamCorruptedexception
            if(o instanceof RequestForGame)
            {
                RequestForGame r=(RequestForGame)o;
                String userToPlayWith=r.getUserToPlayWith();
                if(userToPlayWith.equals(nickname))
                {
                    String message="Playing with yourself makes your palms hairy, choose another opponent";
                    outToClient.writeObject(message);
                }
                else
                {
                System.out.println("received request to play with "+userToPlayWith+". starting game");
                ClientRepresentative client1=model.getClient(nickname);
                ClientRepresentative client2=model.getClient(userToPlayWith);
                ServerGameThread s=new ServerGameThread(client2,client1,client2.getInStream(),client1.getInStream(),client1.getOutStream(),client2.getOutStream());
                }
            }
            else if(o instanceof String)
            {
                String s=(String) o;
                if(s.equals("i want to quit"))
                {
                    model.deleteClient(nickname);
                    inFromClient.close();
                    String q="quit";
                    outToClient.writeObject(q);
                    connectionSocket.close();
                    System.out.println(nickname+"has quit without exc");
                }
            }
        }
    } catch (EOFException e) {
        System.out.println(nickname+" has quit");
    }
    catch (SocketException e)
    {
        System.out.println(nickname+" has quit");
    }

    catch (Exception e) {

        e.printStackTrace();
    }
}

}
 public class ServerGameThread extends Thread {

private ClientRepresentative client1,client2;
private ObjectInputStream inFromClient1,inFromClient2;
private ObjectOutputStream outToClient1,outToClient2;
private Field gameField; 
public ServerGameThread(ClientRepresentative client1, ClientRepresentative client2,ObjectInputStream inFromClient1,ObjectInputStream inFromClient2,ObjectOutputStream outToClient1,ObjectOutputStream outToClient2)
{
    System.out.println("startin game thred");
    this.client1=client1;//client 1 goes first
    this.client2=client2;//client 2 started game


        this.inFromClient1=inFromClient1;
        this.inFromClient2=inFromClient2;
        this.outToClient1=outToClient1;
        this.outToClient2=outToClient2;


        gameField=new Field();
        System.out.println("check");
        start();
}
public void run()
{
    System.out.println("Starting game. players: "+client1.getNickname()+";"+client2.getNickname());
    try {
        outToClient1.writeObject(gameField);
        outToClient2.writeObject(gameField);
        while(true)
        {
            try {
                System.out.println("listening to "+client1.getNickname());
                Object o1=inFromClient1.readObject();//read move from client 1.**//StreamCorruptedexception**

                while(!(o1 instanceof PlayerMove))
                {
                    o1=inFromClient1.readObject();//read move from client 1.
                }
                PlayerMove move1=(PlayerMove)o1;
                System.out.println("received move "+move1+" sending to "+client2.getNickname());
                outToClient2.writeObject(move1);
                System.out.println("listening to "+client2.getNickname());
                Object o2=inFromClient2.readObject();//read move from client 1.
                while(!(o2 instanceof PlayerMove))
                {   
                    o2=inFromClient2.readObject();//read move from client 1.
                }
                PlayerMove move2=(PlayerMove)o2;
                System.out.println("received move "+move2+" sending to "+client1.getNickname());
                outToClient1.writeObject(move2);
            }
                catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}    

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();
        }
    }
}

向服务器发送对象的客户端代理,方法由GUI中的用户操作触发

  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();
    }
}

}

问题回答

如果您执行以下操作,则可能会出现此问题:

  1. construct a new ObjectInputStream or ObjectOutputStream over the same socket instead of using the same ones for the life of the socket (invalid type code AC);
  2. use another kind of stream over the same socket as well; or
  3. use the object streams to read or write something that isn t an object and get that process out of sync.

In intellij this is how I solved for Java. Go to build> gradle enter image description here

then change the java version to lower one. enter image description here

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

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

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

private void readObject( ObjectInputStream objectInputStream ) throws IOException

则必须调用objectInputStream.defaultReadObject(),并在进一步读取输入流之前调用,以正确初始化对象。

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

此链接提供了有关该流程的更多信息:http://osdir.com/ml/java.sun.jini/2003-10/msg00204.html一

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

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

无论何时读取ObjectInputStream,如果它在多个线程之间共享,只需在synchronizedblock中访问它。


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

...
String nickname = null;
synchronized (inFromClient) {
    nickname = (String) inFromClient.readObject();
}

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

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

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

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

我的问题是gradle JVM配置不正确。请检查设置中是否使用了兼容的JDK

1. File | Setting | Build, Execution, Deployment | Build Tools | Gradle | Gradle JVM (Here is my problem)

2. Please select the correct your own JDK directory installation in the local computer (default dir in windows is located at the path "C:Program FilesJavajdk-17")

希望能帮助大家





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签