java.io.StreamCorruptedException:无效的流头:4C756E69
如果这个问题被问了很多次,但经过几个小时的谷歌搜索/实验,我还没有解决我的问题,我深表歉意 我正试图通过UDP套接字将一个对象(ServerPlayer)从我的服务器发送到我的客户端,当客户端收到数据包时,我得到一个无效的流头。我不确定是什么原因修改了数据,导致报头损坏/不存在 发件人线程:java.io.StreamCorruptedException:无效的流头:4C756E69,java,udp,objectinputstream,Java,Udp,Objectinputstream,如果这个问题被问了很多次,但经过几个小时的谷歌搜索/实验,我还没有解决我的问题,我深表歉意 我正试图通过UDP套接字将一个对象(ServerPlayer)从我的服务器发送到我的客户端,当客户端收到数据包时,我得到一个无效的流头。我不确定是什么原因修改了数据,导致报头损坏/不存在 发件人线程: //Thread loop @Override public void run() { System.out.println("Thread " + threadCount + " running"
//Thread loop
@Override
public void run()
{
System.out.println("Thread " + threadCount + " running");
//Test object transmission code.
data = new byte[2048];
// -----------------------------------------------------------------------------------
// TRANSMISSION SETUP/OBJECT TRANSFER
try
{
//In case of delay
socket.setSoTimeout(1000);
//Object Transmission setup
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bStream);
oo.writeObject(p);
oo.close();
//Transmit object
data = bStream.toByteArray();
packet = new DatagramPacket(data, data.length, address, 4415);
socket.send(packet);
// -----------------------------------------------------------------------------------
// GAME LOOP
while(socket.getSoTimeout() > 0)
{
}
// -----------------------------------------------------------------------------------
// GET TO THE CHOPPA CODE BELOW
}
catch (SocketException e)
{
System.out.println("Player " + username + " timed out");
}
catch (IOException e)
{
System.out.println("Server: ");
e.printStackTrace();
}
}
客户/接收人:
public MultiplayerGameStart() throws IOException
{
address = InetAddress.getByName("127.0.0.1");
serverip = InetAddress.getByName(NetSettingsManager.ipAdd);
}
@Override
public void run()
{
//Packet byte array
data = new byte[2048];
try
{
//Send connection REQ
socket = new DatagramSocket(4415, address);
data = PacketUtil.intTobyte(NetSettingsManager.NET_FUNCTION.REQ.getFunctionCode(), data.length);
packet = new DatagramPacket(data, data.length, serverip, serverport);
socket.send(packet);
//Wait for ACK
packet = new DatagramPacket(data, data.length);
socket.receive(packet);
//Converts ACK bytes to int to be read. If ACK code is correct, continue.
if(PacketUtil.byteToint(packet.getData()) == NetSettingsManager.NET_FUNCTION.ACK.getFunctionCode())
{
//Returns username to be checked on playerlist.
System.out.println("Logging into server..."); //DEBUG output
data = NetSettingsManager.username.getBytes();
packet = new DatagramPacket(data, data.length, serverip, serverport);
socket.send(packet);
//Stub code below. Will receive player object generated by server.
packet = new DatagramPacket(data, data.length);
socket.receive(packet);
ObjectInputStream iStream = new ObjectInputStream(new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength()));
//iStream.reset();
ServerPlayer messageClass = (ServerPlayer) iStream.readObject();
iStream.close();
space = new PlayState();
space.addEntity(new ClientPlayer(received));
}
}
catch (IOException e)
{
System.out.println("Client: ");
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
System.out.println("Client: ");
e.printStackTrace();
}
}
ServerPlayer(注意,我在这个示例中省略了我的函数,但如果需要,我可以提供它们)
堆栈跟踪:
java.io.StreamCorruptedException: invalid stream header: 4C756E69
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at client.multiplayer.MultiplayerGameStart.run(MultiplayerGameStart.java:80)
at java.lang.Thread.run(Unknown Source)
但可悲的是,我现在越来越
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(Unknown Source)
at java.io.ObjectInputStream.readUTF(Unknown Source)
at java.io.ObjectStreamClass.readNonProxy(Unknown Source)
at java.io.ObjectInputStream.readClassDescriptor(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at client.multiplayer.MultiplayerGameStart.run(MultiplayerGameStart.java:80)
at java.lang.Thread.run(Unknown Source)`
摆脱对
reset()
的调用。它们没有添加任何内容,我相信对bStream.reset()的服务器端调用
正在删除创建ObjectOutputStream
时写入的头
此外,当您构造ByteArrayInputStream
时,应该使用三个参数变量,从数据报数据包传递getOffset()
和getLength()
将来,当问这样的问题时,请发布异常的实际堆栈跟踪,以及足够的代码,以验证异常是否发生在您认为发生的位置(在本例中,是full receive方法)
编辑:客户端和服务器似乎都发送和接收到同一端口(4415)。根据您提供的其他调试信息,我相信客户机正在接收它试图发送到服务器的初始数据报。尝试为每个端口使用不同的端口(并使用常量,例如
客户端端口
和服务器端口
来指定它们)。非常感谢您的建议/响应,但遗憾的是,它仍然会引发相同的错误。我用你的建议更新了我的帖子。那样的话,是时候进行一些调试了。首先是验证您接收的内容是否与发送的内容相同:在服务器和客户端上打印数据的前几个字节。服务器发送的内容:[B@39fae86客户收到的信息:[B@68e26d2e我相信头两个字节的头是正确的?因此,在数据进入ObjectInputStream之前,有什么东西正在对数据进行操作,导致它抛出该异常?打印实际的字节,而不是toString()
。在服务器上:System.err.println(“sent”+data.length+“bytes:+data[0]+,“+data[1]+,”+数据[2]+“,”+数据[3])
在客户端上,您需要做同样的事情,但您需要考虑偏移量。在两侧打印数据包长度非常重要感谢您的持续回复。这非常有帮助。服务器:发送250字节:-84,-19,0,5 |客户端:偏移量:0收到8字节:76117110105116有大量数据未被接收。使用TCP套接字传输这些对象,然后切换到UDP套接字以进行我的游戏循环是否明智?getSoTimeout()上的循环>0
简直是浪费时间。反复测试没有任何意义,除非您正在更改它以打破循环,在这种情况下,您滥用了该工具。循环是在几次修订后遗留下来的代码/实验。我可能应该删除它,因为它确实没有任何用途,而是在ti上我知道它已投入使用。感谢您的回复:)循环将永远不会终止,因为套接字超时已设置为10000。这里出现严重错误。
server:sent 243 bytes: -84,-19,0,5 | client: received 8 bytes -84, -19, 0, 5
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(Unknown Source)
at java.io.ObjectInputStream.readUTF(Unknown Source)
at java.io.ObjectStreamClass.readNonProxy(Unknown Source)
at java.io.ObjectInputStream.readClassDescriptor(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at client.multiplayer.MultiplayerGameStart.run(MultiplayerGameStart.java:80)
at java.lang.Thread.run(Unknown Source)`