How to use readObject() twice in socket of Java?

折月煮酒 提交于 2019-12-11 09:53:14

问题


I used the ObjectStream in Socket to transport the class. The client transports two different data in same class, but the server gets the second data that is same as the first data. It is strange!

Here is my code of client:

public Client()
{   
        MessageClass messageobject=new MessageClass("login");
        messageobject.SetLoginUserInfo("18580409","12345","magicgiant");

    try
    {
        client=new Socket("localhost",1234);
        System.out.println("Connected!");
        ObjectOutputStream out=new ObjectOutputStream(client.getOutputStream());
        out.writeObject(messageobject);
        out.flush();
        System.out.println(1);

        messageobject.inquire=true;
        messageobject.SetLoginUserInfo("122131","21312","dfsd");
        out.writeObject(messageobject);
        out.flush();
        System.out.println(2);
    }
    catch(Exception e)
    {
        System.out.println(e);
    }
}

Here is my server:

public void run()
{  
  try
  {
     is=new ObjectInputStream(client.getInputStream());
  }
  catch (Exception ex)
  {
     System.out.println(ex);
  }

  while(true){

   try
   {  
      MessageClass messageobject = (MessageClass)is.readObject();   
      System.out.println(messageobject.GetLoginId()+messageobject.GetLoginPassword());
      idSocketItem = new IdSocket(messageobject.GetLoginId(),client,messageobject);
      s.idSocketList.addElement(idSocketItem);
    }
    catch (Exception ex)
    {
       System.out.println(ex);
     }

   }    
}

The System.out in server should be

1858040912345
12213121312

But the real result is

1858040912345
1858040912345

I have tried to cancel the flush(), but it does not work. Where is the problem?


回答1:


The problem is that you're writing the same reference twice:

out.writeObject(messageobject);
out.flush();
System.out.println(1);

messageobject.inquire=true;
messageobject.SetLoginUserInfo("122131","21312","dfsd");
out.writeObject(messageobject);

ObjectOutputStream caches the fact that you've written that reference, and just emits a token to refer to the previous value. Three options to consider:

  • (Preferred, IMO): Create a new object instead of modifying the existing one
  • Call writeUnshared() instead of writeObject():

    This method is identical to writeObject, except that it always writes the given object as a new, unique object in the stream (as opposed to a back-reference pointing to a previously serialized instance).

  • Call reset() on the stream after writing the first object:

    Reset will disregard the state of any objects already written to the stream. The state is reset to be the same as a new ObjectOutputStream. The current point in the stream is marked as reset so the corresponding ObjectInputStream will be reset at the same point. Objects previously written to the stream will not be refered to as already being in the stream. They will be written to the stream again.

I prefer the first version as logically you've got two different messages - so they should be two different objects.

Additionally, I'd strongly encourage you to start following Java naming conventions, and make all your fields private to encourage encapsulation.



来源:https://stackoverflow.com/questions/17009368/how-to-use-readobject-twice-in-socket-of-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!