java.io.StreamCorruptedException:无效类型代码:00
所以基本上我在写一个客户端-服务器多人游戏。 我有一个SeverCommunicationsRead,如果他收到请求,就会创建一个游戏线程,然后创建一个游戏线程。 当我发送RequestForGame时,会引发java.io.StreamCorruptedException异常:无效类型代码:00 我假设这是因为两个线程都试图读取相同的ObjectInputStream,我对它的工作原理没有太多的了解,我只知道如何使用它。你能帮我了解问题所在以及如何解决吗? 谢谢:) model.addClient方法,但我认为问题不在这里java.io.StreamCorruptedException:无效类型代码:00,java,multithreading,sockets,objectoutputstream,Java,Multithreading,Sockets,Objectoutputstream,所以基本上我在写一个客户端-服务器多人游戏。 我有一个SeverCommunicationsRead,如果他收到请求,就会创建一个游戏线程,然后创建一个游戏线程。 当我发送RequestForGame时,会引发java.io.StreamCorruptedException异常:无效类型代码:00 我假设这是因为两个线程都试图读取相同的ObjectInputStream,我对它的工作原理没有太多的了解,我只知道如何使用它。你能帮我了解问题所在以及如何解决吗? 谢谢:) model.addClie
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
- 在同一套接字上使用另一种流;或者
- 使用对象流读取或写入非对象的内容,会导致不同步
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