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 --------------------编程问答-------------------- 出错的相关代码贴一下 --------------------编程问答--------------------
我并没有传送一个集合,只是传送了这个类中的一个字符串属性,为什么也会出现这个异常? --------------------编程问答-------------------- 所有的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。。。。。
传送跟接收的代码一样一样
--------------------编程问答--------------------
代码已经贴出来了,麻烦看一下 --------------------编程问答-------------------- 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());
这个问题困扰了很久,特别希望解决掉 --------------------编程问答--------------------
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 里的所有东西,它只读取有效字节。
因为你是实时传送,所以你读到的东西可能只是发送的一部分。
造成错误。 --------------------编程问答--------------------
那就是直接的 InputStream 了。
InputStream.read() 并不会读取 InputStream 里的所有东西,它只读取有效字节。
因为你是实时传送,所以你读到的东西可能只是发送的一部分。
造成错误。
那我应该如何解决呢?
不使用InputStream.read()方法的话有什么别的替代方法吗?
还是说不使用InputStream呢? --------------------编程问答-------------------- 用它没问题。
但你要了解它怎么读,怎么避免读的不全。 --------------------编程问答--------------------
用它没问题。
但你要了解它怎么读,怎么避免读的不全。
我还是有些不理解您说的话,我使用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;
}
你先想着怎么解决问题。给你个例子吧
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()函数。 --------------------编程问答--------------------
Socket传送部分代码
// 接收
public void run() {
try {
while ((mCommend = (Command) mInputStream.readObject()) != null{}
}catch。。。。。
传送跟接收的代码一样一样
如果传送跟接收代码一样,而且传送用的是ObjectOutputStream的话,那么ObjectOutputStream 不能直接追加,因为每次追加都会添加进一个Header。
所以反序列化的时候,才会出现这个异常。
其中一个解决方案是 重写下ObjectOutputStream的writeStreamHeader()函数。
这样说来,问题出在ObjectOutputStream的机制上,如果换一个,比如DataOutputStream,不知还会不会出现这种情况,我先试一试 --------------------编程问答--------------------
是让你按字节分段读取,一次只读一小段,因为是实时读嘛。
如果读到 -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呢 --------------------编程问答--------------------
是让你按字节分段读取,一次只读一小段,因为是实时读嘛。
如果读到 -1,说明没有可用字节可供读取,那你就等一下,接着读。
有的时候好用,帮帮忙,谢谢!
补充:Java , Java SE