简体   繁体   中英

Sending a PriorityQueue over Socket in Java sends an empty queue

I have two programs - Server and a Client. Basically the job of the server is to maintain an ArrayList of objects of some class 'Item'. Items can be added to the ArrayList or existing items can be altered on the Client app's request. Occasionally the Client App has to receive some of the Items that are contained in the list and that is where the problem comes from. The Item Class has a PriorityQueue of other objects (that are serializable) as an instance variable. The problem is that when the server sends some items the client receives everything but the priority queue for each item is empty (all the other instance variables of the Item objects are received correctly).

Now the code:
This is the part of the Item Class that is connected to the problem:

public class Item implements Serializable   
{  
    ...Some instance variables...   
    PriorityQueue<Bid> pq;

    public Item(...)  
    {      
        pq = new ProrityQueue<Bid>(); 
    }  

    public void addStuff(Stuff bid)  
    {  
        this.pq.add(bid);  
    }  

    ...other methods...      
}  

To send the ArrayList that the client requested I just to this on the server side

ObjectOutputStream oos = new ObjectOutputStream(serverSocket.getOutputStream);
oos.writeObject(someArrayList<Item>);  

and on the client side

ObjectInputStream ois = new ObjectInputStream(serverSocket.getInputStream);  
ArrayList<Item> tempList = (ArrayList<Item>) ois.readObject();  

I find it really strange that the client receives every single object it has to receive and all of its instance variables including the PriorityQueue but the PriorityQueue is empty. Why are the Objects in the PriorityQueue the only thing that is not received by the Client? Is there something extra I should know about sending a List of objects that have some collection of other objects within them over a socket?

EDIT : I am posting part of the code for further details. In fact for the communication between the server and the client I use ClientCommunications Class and ServerCommunication Class that handle everything so that the two apps don't have to deal with the sockets.

To send some of the items that are requested by the client I have

ArrayList<Item> list = handleItemsRequest(rim); 
//this uses the server output stream to transfer an object to the client's output stream   
comms.sendItems(list);  

Code for the sendItems(list) method:

public void sendItems(ArrayList<Item> items)
{
    try
    {
        //oos is the output stream of the server socket
        oos.writeObject(items);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

where handleItemsRequest() is a method that takes some constraints and then return only the items that match them:

public ArrayList<Item> handleItemsRequest(RequestItemsMessage rim)  
{  
    //it is the new array list that consist of items matching the conditions
    ArrayList<Item> it = new ArrayList<Item>();     
    //items is the arrayList maintained by the server  
    for (Item item : items)  
    {  
       if (item.matchesConditions)  
       {  
           it.add(item);
       }
    }

    //it contains all the right items and the priorityQueue for each item has everything that it has to have  
    return it;  
}  

Then the client app receives the list by calling

//this comms variable is different from the one in the server and is a par of a different class  
ArrayList<Item> list = comms.receiveItems(); 

Code for the receiveItems():

public ArrayList<Item> receiveItems()
{
    try
    {
        ArrayList<Item> list = (ArrayList<Item>) ois.readObject();
        return list;
    }
    catch(ClassNotFoundException | IOException e)
    {
        e.printStackTrace();
    }

    return null;
}

Now the client has all the items that had to be sent but their priority queues are empty.
There is much more code but it is not relevant to this problem and I needn't post it all.

SOLUTION It turns out that before sending the list the OutputStream of the server has to be reset. Otherwise the client would keep getting the old instance again and again. Big thanks to EJP for pointing out the problem!

Do you ever close the stream? Try calling oos.close() after oos.writeObject() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM