问题描述
- objectinputstream readobject 为何只能读取第一次写入的值
-
public class TransEntity implements Serializable//传输信息实体封装类
{
private static final long serialVersionUID = 1L;
private String operaType;//用户操作类型;如发送文本消息,发送语音消息,发送音频消息
private String responseTags;//网络响应状态;如“登录成功”、“登录失败”、“注册成功”、“注册失败”
private String requestTags;//网络请求标记;请求发送文本消息,语音消息,音频消息
private User sender;//发送方;
private User receiver;//接收方;
private ArrayList> buddylist;//好友列表信息;
private String time;//系统时间;
private ArrayList> inputGeneralMsgList;//通用信息
private HashMap outGeneralMsgMap;
private String path;public String getUserOperaType()
{
return operaType;
}
public void setUserOperaType(String operaType)
{
this.operaType = operaType;
}
public String getResponseTags()
{
return responseTags;
}
public String setResponseTags(String responseTags)
{
return this.responseTags = responseTags;
}
public void setRequestTags(String requestTags)
{
this.requestTags = requestTags;
}public String getRequestTags()
{
return requestTags;
}
public User getSender()
{
return sender;
}
public void setSender(User sender)
{
this.sender = sender;
}
public User getReceiver()
{
return receiver;
}
public void setReceiver(User receiver)
{
this.receiver = receiver;
}
public ArrayList> getList()
{
return buddylist;
}
public void setList(ArrayList> buddylist)
{
this.buddylist = buddylist;
}
public String getImagePath()
{
return path;
}
public void setImagePath(String path)
{
this.path = path;
}
public void setGeneralMessagefrom(ArrayList> inputGeneralMsgList)
{
this.inputGeneralMsgList = inputGeneralMsgList;
}
public ArrayList> getGeneralMessagefrom()
{
return inputGeneralMsgList;
}
public void setGeneralMessageto(HashMap outGeneralMsgMap)
{
this.outGeneralMsgMap = outGeneralMsgMap;
}
public HashMap getGeneralMessageto()
{
return outGeneralMsgMap;
}
public void setSysTime(String time)
{
this.time = SysTime.getDateTime();
}
public String getSysTime()
{
return time;
}
}服务端核心代码
public class ServerThread extends Thread
{
private static ObjectInputStream ois = null;
private static ObjectOutputStream oos = null;
private ArrayList> list = null;
private ArrayList> outgeneralMsgList = null;
private Socket socket = null;private TransEntity trans = null;
private boolean FLAGS_IsFirstLogin = true;
private boolean FLAGS_LoginSucess = false;
private boolean FLAGS_RegisterSucess = false;
private boolean FLAGS_OnLine = false;
private User user = null;
private User receiver = null;
private Timer timer = new Timer();
public ServerThread(Socket socket)
{
this.socket = socket;
try
{
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
}
catch (IOException e)
{e.printStackTrace();
}}
public void run()
{
try
{while(true)
{if(socket.isClosed() == false && socket.isConnected() == true)
{try { if(ois!=null)
{
trans = (TransEntity) ois.readObject();}
} catch(java.net.SocketException e) { System.out.println("客户端已经关闭。。。。。。。"); break; } catch(ClassNotFoundException e)
{
System.out.println("--------空指针异常---------");}
catch(java.io.EOFException e)
{
System.out.println("客户端已经关闭。。。。。。。");
}}
if(trans!=null)
{
user = trans.getSender();
receiver = trans.getReceiver();
if(trans.getUserOperaType()!=null)
{
System.out.println("----------trans.getUserOperaType() :------------"+(trans.getUserOperaType()));
if(FLAGS_IsFirstLogin == true&&(UserOperaType.LOGIN.equals(trans.getUserOperaType())))
{ //首次登录,一般情形下的客户端发过来的登录操作请求做处理,非掉线后的自动登录;
System.out.println("--------server---socket :------"+(socket));
FLAGS_LoginSucess = setLogin();}
if(FLAGS_LoginSucess)
{
FLAGS_IsFirstLogin = false;System.out.println("----------trans.getUserOperaType() :------------"+(trans.getUserOperaType()));
......为何此次只能输出第一次读入的数据
if(UserOperaType.SEND_MESSAGE.equals(trans.getUserOperaType()))
{
System.out.println("-------UserOperaType.SEND_MESSAGE ---------");
System.out.println(trans.getGeneralMessageto().get("outMsg").toString());
if(trans.getGeneralMessageto()!=null)//若getGeneralMessageto()返回值不为空,则可以向数据库写入信息;
{System.out.println("-------服务端:---发送方 写入普通信息到数据库,如文字消息;-----------");
SysCtlVar.dbBasicOperation.writeGeneralMessage(trans);// 发送方 写入普通信息到数据库,如文字消息;
//trans.setGeneralMessageto(null);}
trans.setUserOperaType(null);
}oos.writeObject(trans);
oos.flush();}
}}
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{}
}}
客户端核心代码
while(SysCtlVar.FlAGS_LoginSuccess)
{
// System.out.println("--------------while SysCtlVar.FlAGS_LoginSuccess -------------");
try
{try
{SysCtlVar.trans = (TransEntity)SysCtlVar.ois.readObject();
if(SysCtlVar.inputGeneralMsgList!=null)
synchronized(SysCtlVar.inputGeneralMsgList)
{
SysCtlVar.inputGeneralMsgList = SysCtlVar.trans.getGeneralMessagefrom();
SysCtlVar.inputGeneralMsgList.notify();
}synchronized(SysCtlVar.outGeneralMsgMap)
{
try
{
System.out.println("------- SysCtlVar.outGeneralMsgMap.wait----------");
SysCtlVar.outGeneralMsgMap.wait();//等待直到有输入的时候,才把消息发送出去
System.out.println("---------------客户端: 正在发送消息。。。。。。------------------");
System.out.println("------- SysCtlVar.outGeneralMsgMap:----------"+(SysCtlVar.outGeneralMsgMap.get("outMsg").toString()));
SysCtlVar.trans.setUserOperaType(UserOperaType.SEND_MESSAGE);
SysCtlVar.trans.setGeneralMessageto(SysCtlVar.outGeneralMsgMap);
System.out.println("------- SysCtlVar.trans.getGeneralMessageto():----------"+(SysCtlVar.trans.getGeneralMessageto().get("outMsg").toString()));
try
{SysCtlVar.oos.writeObject(SysCtlVar.trans);
SysCtlVar.oos.flush();
}
catch (IOException e)
{e.printStackTrace();
}}
catch (InterruptedException e)
{e.printStackTrace();
}}
}
catch (ClassNotFoundException e)
{e.printStackTrace();
}
}
catch (StreamCorruptedException e1)
{e1.printStackTrace();
}
catch (IOException e1)
{e1.printStackTrace();
}}
}客户端 数据输入部分
/**
调试过程中,你将看到客户端输入的消息为h(第一条消息),www(第二条消息),a(第三条消息)
但是服务端只有第二条消息的值;
*/
//------------------发送消息 ----------
//客户端当前会话任务中,选中的消息接收者;
new Thread()
{
public void run()
{
synchronized(SysCtlVar.outGeneralMsgMap)
{
System.out.println("------- 客户端:正在输入要发送的消息----------");
SysCtlVar.outGeneralMsgMap.clear();
SysCtlVar.outGeneralMsgMap.put("outMsg",outMsg);
SysCtlVar.outGeneralMsgMap.put("msgRecver", selectedAccount);
SysCtlVar.outGeneralMsgMap.put("dateTime",SysTime.getDateTime().toString());
SysCtlVar.outGeneralMsgMap.notify();//输入完毕,通知发送任务执行
}
}
}.start();
调试信息(服务器端)服务器已启动,正在监听1345端口
----------trans.getUserOperaType() :------------0
--------server---socket :------Socket[addr=/127.0.0.1,port=38516,localport=1345]
------- list!=null : ---------true
[qq]上线了!
----------qq----------
----------trans.getUserOperaType() :------------0
----------trans.getUserOperaType() :------------6
----------trans.getUserOperaType() :------------6
-------------UserOperaType.GET_AVATARS------------6
我想从服务器获取头像
----------trans.getUserOperaType() :------------7
----------trans.getUserOperaType() :------------7
-------UserOperaType.SEND_MESSAGE ---------
www
-------服务端:---发送方 写入普通信息到数据库,如文字消息;-----------
insert into chat(sender,recver,message,sendtime) values('qq','在水一方','www','2015-04-24 16:15:13')
----------trans.getUserOperaType() :------------7
----------trans.getUserOperaType() :------------7
-------UserOperaType.SEND_MESSAGE ---------
www
-------服务端:---发送方 写入普通信息到数据库,如文字消息;-----------
insert into chat(sender,recver,message,sendtime) values('qq','在水一方','www','2015-04-24 16:15:13')
----------trans.getUserOperaType() :------------7
----------trans.getUserOperaType() :------------7
-------UserOperaType.SEND_MESSAGE ---------
www
-------服务端:---发送方 写入普通信息到数据库,如文字消息;-----------
insert into chat(sender,recver,message,sendtime) values('qq','在水一方','www','2015-04-24 16:15:13')
----------trans.getUserOperaType() :------------7
----------trans.getUserOperaType() :------------7
-------UserOperaType.SEND_MESSAGE ---------
www
-------服务端:---发送方 写入普通信息到数据库,如文字消息;-----------
insert into chat(sender,recver,message,sendtime) values('qq','在水一方','www','2015-04-24 16:15:13')---------------问题补充---------------
单步调试,客户端的输出流正确发送了每一次的客户端输入数据(36分钟前)删除
对于单步调试追踪的结果:客户端每一次发送的trans(它是TransEntity的实例,被序列化的消息实体对象)都是正确的(即,与客户端输入值相同)。但是服务端有ObjectInputStream读入的trans(它也是TransEntity的实例,被序列化的消息实体对象)却没有改变始终是第一次的值
解决方案
调试i下,我怀疑主要还是网络通讯的问题。
解决方案二:
http://bbs.csdn.net/topics/391023812 是不是跟我的这个问题类似