当前位置:编程学习 > JAVA >>

java.io.StreamCorruptedException: Wrong format异常

小弟使用socket向客户端发一个自定义对象,强制转换时出现java.io.StreamCorruptedException: Wrong format异常,不知如何解决
异常信息如下

10-23 02:20:58.687: W/System.err(1276): java.io.StreamCorruptedException: Wrong format: ac
10-23 02:20:58.689: W/System.err(1276):  at java.io.ObjectInputStream.corruptStream(ObjectInputStream.java:701)
10-23 02:20:58.689: W/System.err(1276):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:814)
10-23 02:20:58.689: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
10-23 02:20:58.689: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
10-23 02:20:58.689: W/System.err(1276):  at com.wsst.utils.SocketUtil$1.run(SocketUtil.java:77)
10-23 02:20:58.689: W/System.err(1276):  at java.lang.Thread.run(Thread.java:856)
10-23 02:20:58.689: W/System.err(1276): java.io.StreamCorruptedException: Wrong format: ed
10-23 02:20:58.699: W/System.err(1276):  at java.io.ObjectInputStream.corruptStream(ObjectInputStream.java:701)
10-23 02:20:58.699: W/System.err(1276):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:814)
10-23 02:20:58.699: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
10-23 02:20:58.699: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
10-23 02:20:58.709: W/System.err(1276):  at com.wsst.utils.SocketUtil$1.run(SocketUtil.java:77)
10-23 02:20:58.709: W/System.err(1276):  at java.lang.Thread.run(Thread.java:856)
10-23 02:20:58.709: W/System.err(1276): java.io.StreamCorruptedException: Wrong format: 0
10-23 02:20:58.709: W/System.err(1276):  at java.io.ObjectInputStream.corruptStream(ObjectInputStream.java:701)
10-23 02:20:58.709: W/System.err(1276):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:814)
10-23 02:20:58.709: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
10-23 02:20:58.709: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
10-23 02:20:58.709: W/System.err(1276):  at com.wsst.utils.SocketUtil$1.run(SocketUtil.java:77)
10-23 02:20:58.709: W/System.err(1276):  at java.lang.Thread.run(Thread.java:856)
10-23 02:20:58.719: W/System.err(1276): java.io.StreamCorruptedException: Wrong format: 5
10-23 02:20:58.719: W/System.err(1276):  at java.io.ObjectInputStream.corruptStream(ObjectInputStream.java:701)
10-23 02:20:58.719: W/System.err(1276):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:814)
10-23 02:20:58.719: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
10-23 02:20:58.719: W/System.err(1276):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
10-23 02:20:58.719: W/System.err(1276):  at com.wsst.utils.SocketUtil$1.run(SocketUtil.java:77)
10-23 02:20:58.729: W/System.err(1276):  at java.lang.Thread.run(Thread.java:856) --------------------编程问答-------------------- 反序列化问题。
http://hi.baidu.com/chinalwb/item/bffa8745c7cd522011ee1e6b --------------------编程问答-------------------- 出错的相关代码贴一下 --------------------编程问答--------------------
引用 1 楼 zhuweisyyc 的回复:
反序列化问题。
http://hi.baidu.com/chinalwb/item/bffa8745c7cd522011ee1e6b

我并没有传送一个集合,只是传送了这个类中的一个字符串属性,为什么也会出现这个异常? --------------------编程问答-------------------- 所有的Object传输都是要序列化的,不管集合也好,字符串也好,都是序列化的对象,就会出错。还是贴下你的代码吧。 --------------------编程问答--------------------
引用 4 楼 zhuweisyyc 的回复:
所有的Object传输都是要序列化的,不管集合也好,字符串也好,都是序列化的对象,就会出错。还是贴下你的代码吧。

我通过socket传送的所有对象的类,都实现了Serializable,代码有些长,我贴一下
Command类
package com.wsst.common;


import java.io.Serializable;

public class Command implements Serializable{

private static final long serialVersionUID = 1L; //序列化对象
public static final String CLIENT_INDEX ="ClientIndex"; //指令值(用户唯一标识)command
public static final String GET_PLAYER_COUNT ="GetPlayerCount"; //获取玩家总数command
public static final String GET_ALL_ROOM ="GetAllRoom"; //获取房间信息command
public static final String CREATEROOM ="CreateNewRoom"; //创建新房间command
public static final String GETINROOM ="GetInRoom"; //加入指定房间command
public static final String STARTGAME ="StartGame"; //下发比赛题目command
public static final String USERTABLE ="UserTable"; //本地用户信息command
public static final String REGISTERVALID ="RegisterValid"; //用户提交注册信息command
public static final String TEST = "test";

public String LevelInfo; //题别信息
public String RoomList; //room列表
private String CommendHead;  //command头
private String CommendValue;  //command值
private int ClientIdx; //指令值(用户唯一标识)
private Player player; //玩家对象
private String groupArr; //存放指定级别的题号字符串
private String userInfo; //存放用户注册信息的字符串
private Room room;

public Room getRoom() {
return room;
}
public void setRoom(Room room) {
this.room = room;
}
public String getLevelInfo() {
return LevelInfo;
}
public void setLevelInfo(String levelInfo) {
LevelInfo = levelInfo;
}
public String getUserInfo() {
return userInfo;
}
public void setUserInfo(String userInfo) {
this.userInfo = userInfo;
}
private int RoomID;

public int getRoomID() {
return RoomID;
}
public void setRoomID(int roomID) {
RoomID = roomID;
}

public String getGroupArr() {
return groupArr;
}
public void setGroupArr(String groupArr) {
this.groupArr = groupArr;
}
public  Command(){
     super();
}
public  Command(String head,String value,int index){
super();
CommendHead = head;
CommendValue = value;
ClientIdx = index;
}

public String getRoomList() {
return RoomList;
}
public void setRoomList(String roomList) {
RoomList = roomList;
}
public String getCommendHead() {
return CommendHead;
}
public void setCommendHead(String commendHead) {
CommendHead = commendHead;
}
public String getCommendValue() {
return CommendValue;
}
public void setCommendValue(String commendValue) {
CommendValue = commendValue;
}
public int getClientIdx() {
return ClientIdx;
}
public void setClientIdx(int clientIdx) {
ClientIdx = clientIdx;
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
}
Player类
package com.wsst.common;

import java.io.Serializable;

public class Player implements Serializable {

private static final long serialVersionUID = 1L;   //序列化对象
private String name; //玩家账号昵称
private String ipAdress; //玩家IP
private int clientId; //玩家指令值
private int roomID; //玩家所在的房间号
private String totalScores;         //玩家游戏得分
private String selectedItem;          //玩家某项题目所选答案

public Player(int clientIndex) {
this.clientId = clientIndex;
}

public String getIPAdress() {
return ipAdress;
}

public void setIPAdress(String iPAdress) {
this.ipAdress = iPAdress;
}

public int getClientIdx() {
return clientId;
}
public void setClientIdx(int clientIdx) {
this.clientId = clientIdx;
}

public int getRoomID() {
return roomID;
}

public void setRoomID(int roomID) {
this.roomID = roomID;
}

public String getName() {
return name;
}

public void setName(String Name) {
this.name = Name;
}

public String getTotalScores() {
return totalScores;
}

public void setTotalScores(String TotalScores) {
this.totalScores = TotalScores;
}

public String getSelectedItem() {
return selectedItem;
}

public void setSelectedItem(String SelectedItem) {
this.selectedItem = SelectedItem;
}
}

Socket传送部分代码
// 接收
public void run() {
 try {
   while ((mCommend = (Command) mInputStream.readObject()) != null{}
}catch。。。。。
传送跟接收的代码一样一样

--------------------编程问答--------------------
引用 2 楼 defonds 的回复:
出错的相关代码贴一下

代码已经贴出来了,麻烦看一下 --------------------编程问答-------------------- mInputStream 是什么类?ObjectInputStream 吗?它怎么初始化的 --------------------编程问答--------------------
引用 6 楼 loveztbdcz 的回复:
Quote: 引用 2 楼 defonds 的回复:

出错的相关代码贴一下

代码已经贴出来了,麻烦看一下


private Socket mSocket;
private ObjectInputStream mInputStream;
private ObjectOutputStream mOutputStream;
private Command mCommend = null;
private int romNum = 10;
private boolean 易做图 = false; // false 验证未通过;true 验证通过
private String levelStr = null; // 存放服务器端的题库名称及大小的字符串
private Map<String, String> userinfo_map = null;

public ThreadServer(Socket socket) {
try {
this.mSocket = socket;
// 创建输入/输出流
mInputStream = new ObjectInputStream(socket.getInputStream());
mOutputStream = new ObjectOutputStream(socket.getOutputStream());

这个问题困扰了很久,特别希望解决掉 --------------------编程问答--------------------
引用 7 楼 defonds 的回复:
mInputStream 是什么类?ObjectInputStream 吗?它怎么初始化的

private Socket mSocket;
private ObjectInputStream mInputStream;
private ObjectOutputStream mOutputStream;
private Command mCommend = null;
private int romNum = 10;
private boolean 易做图 = false; // false 验证未通过;true 验证通过
private String levelStr = null; // 存放服务器端的题库名称及大小的字符串
private Map<String, String> userinfo_map = null;

public ThreadServer(Socket socket) {
try {
this.mSocket = socket;
// 创建输入/输出流
mInputStream = new ObjectInputStream(socket.getInputStream());
mOutputStream = new ObjectOutputStream(socket.getOutputStream());

这个问题困扰了很久,特别希望解决掉 --------------------编程问答-------------------- 那就是直接的 InputStream 了。
InputStream.read() 并不会读取 InputStream 里的所有东西,它只读取有效字节。
因为你是实时传送,所以你读到的东西可能只是发送的一部分。
造成错误。 --------------------编程问答--------------------
引用 10 楼 defonds 的回复:
那就是直接的 InputStream 了。
InputStream.read() 并不会读取 InputStream 里的所有东西,它只读取有效字节。
因为你是实时传送,所以你读到的东西可能只是发送的一部分。
造成错误。


那我应该如何解决呢?
不使用InputStream.read()方法的话有什么别的替代方法吗?
还是说不使用InputStream呢? --------------------编程问答-------------------- 用它没问题。
但你要了解它怎么读,怎么避免读的不全。 --------------------编程问答--------------------
引用 12 楼 defonds 的回复:
用它没问题。
但你要了解它怎么读,怎么避免读的不全。


我还是有些不理解您说的话,我使用InputStream.read()方法,那我怎么去了解它是如何读的呢? --------------------编程问答-------------------- 你先想着怎么解决问题。给你个例子吧
				int len = buildShort(bytes2[0], bytes2[1]);
byte[] recvData = new byte[len];
int totalCount = 0;
int readCount = 0;
while (totalCount < len ) {
readCount = inputStream.read(recvData, totalCount, len - totalCount);
if (readCount == -1)
throw new BaseException(GlobalConstant.ERROR_CODE_40032);
totalCount = readCount + totalCount;
}
--------------------编程问答--------------------
引用 14 楼 defonds 的回复:
你先想着怎么解决问题。给你个例子吧
				int len = buildShort(bytes2[0], bytes2[1]);
byte[] recvData = new byte[len];
int totalCount = 0;
int readCount = 0;
while (totalCount < len ) {
readCount = inputStream.read(recvData, totalCount, len - totalCount);
if (readCount == -1)
throw new BaseException(GlobalConstant.ERROR_CODE_40032);
totalCount = readCount + totalCount;
}


我理解上面例子的含义是:一直读取输入流【while (totalCount < len )】,直到不满足条件。我想问一下,(Command) mInputStream.readObject()这个是不是也应该有方法不断读取里面的对象,我想找到其中某个匹配的Command?我试了一下,while (mInputStream.readObject().equals(true))这样问题好像更多了,异常还是会出现,希望帮忙指导一下。
--------------------编程问答-------------------- 是让你按字节分段读取,一次只读一小段,因为是实时读嘛。
如果读到 -1,说明没有可用字节可供读取,那你就等一下,接着读。 --------------------编程问答-------------------- Socket传送部分代码
// 接收
public void run() {
 try {
   while ((mCommend = (Command) mInputStream.readObject()) != null{}
}catch。。。。。
传送跟接收的代码一样一样

如果传送跟接收代码一样,而且传送用的是ObjectOutputStream的话,那么ObjectOutputStream 不能直接追加,因为每次追加都会添加进一个Header。
所以反序列化的时候,才会出现这个异常。

其中一个解决方案是 重写下ObjectOutputStream的writeStreamHeader()函数。 --------------------编程问答--------------------
引用 17 楼 boblxj0815 的回复:
Socket传送部分代码
// 接收
public void run() {
 try {
   while ((mCommend = (Command) mInputStream.readObject()) != null{}
}catch。。。。。
传送跟接收的代码一样一样

如果传送跟接收代码一样,而且传送用的是ObjectOutputStream的话,那么ObjectOutputStream 不能直接追加,因为每次追加都会添加进一个Header。
所以反序列化的时候,才会出现这个异常。

其中一个解决方案是 重写下ObjectOutputStream的writeStreamHeader()函数。

这样说来,问题出在ObjectOutputStream的机制上,如果换一个,比如DataOutputStream,不知还会不会出现这种情况,我先试一试 --------------------编程问答--------------------
引用 16 楼 defonds 的回复:
是让你按字节分段读取,一次只读一小段,因为是实时读嘛。
如果读到 -1,说明没有可用字节可供读取,那你就等一下,接着读。



/** 
     * 对象转数组 
     * @param obj 
     * @return 
     */  
    public byte[] toByteArray (Object obj) {     
        byte[] bytes = null;     
        ByteArrayOutputStream bos = new ByteArrayOutputStream();     
        try {       
            ObjectOutputStream oos = new ObjectOutputStream(bos);        
            oos.writeObject(obj);       
            oos.flush();        
            bytes = bos.toByteArray ();     
            oos.close();        
            bos.close();       
        } catch (IOException ex) {       
            ex.printStackTrace();  
        }     
        return bytes;   
    }  
      
    /** 
     * 数组转对象 
     * @param bytes 
     * @return 
     */  
    public Object toObject (byte[] bytes) {     
        Object obj = null;     
        try {       
            ByteArrayInputStream bis = new ByteArrayInputStream (bytes);       
            ObjectInputStream ois = new ObjectInputStream (bis);       
            obj = ois.readObject();     
            ois.close();  
            bis.close();  
        } catch (IOException ex) {       
            ex.printStackTrace();  
        } catch (ClassNotFoundException ex) {       
            ex.printStackTrace();  
        }     
        return obj;   
    }  

这两个方法有什么问题吗,为什么返回的结果是NULL呢 --------------------编程问答--------------------
引用 16 楼 defonds 的回复:
是让你按字节分段读取,一次只读一小段,因为是实时读嘛。
如果读到 -1,说明没有可用字节可供读取,那你就等一下,接着读。


有的时候好用,帮帮忙,谢谢!
补充:Java ,  Java SE
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,