Question

I have written a program (java sockets) where a multi-threaded server can connect to multiple clients. In order to communicate with a single client, the server program has one DataInputStream and one DataOutputStream for each client. I want to broadcast a message from the server to the clients one by one. Each client can respond back differently. Depending on the response, the server takes it next action. In fact I am trying to find which client contains a certain file. To broadcast the message to all the clients I add the DataOutputStream for each client into a HashSet.

private static HashSet<DataOutputStream> comChannels = new HashSet<DataOutputStream>();

I can iterate through the items in the HashSet to broadcast any message to the clients. I then broadcast the fileName of the file I am looking for from the server. When a client finds that file in one if its directory it sends a positive response back. If a client does not have that file it sends back a negative response.

The problem I am facing is I cannot get a reply from the clients. When I create a client thread, I create a corresponding DataInputStream for the client as well. I tried to create a HashSet of ArrayList where each ArrayList contains the DataOutputStream and DataInputStream for one single client.

HashSet<ArrayList<Object>> comChannels = new HashSet<ArrayList<Object>>();

I then create an ArrayList containing the input and output stream of a client every time a new client thread is created which I then add to the HashSet of ArrayLists. I thought i can iterate through the HashSet which would return an ArrayList in each iteration. I can then select the 1st object of the list and that would be my outputstream and the 2nd object would be my inputstream. But this does not work.

for (ArrayList<Object> client  : comChannels) {
        //select outputstream from the Arraylist and write message to client
        //select inputstream from the Arraylist and read response from client
}

How can I broadcast and get replies from clients in a way where I can identify which response came from which client? Please note that I want to send the message to one client at a time and terminate the program as soon as a positive response comes back. This saves me from sending the message to all the clients unnecessarily. So creating separate HashSets of DataInputStreams and DataOutputStreams and then writing to all the clients and reading in all the different responses is not feasible.

Was it helpful?

Solution

A pair of streams representing a client is a domain concept in your application and should probably be captured in a meaningful class. Something like this at a bare minimum:

public class Client {
    public DataOutputStream outStream;
    public DataInputStream  inStream; 

    public Client(DataOutputStream out, DataInputStream in) {
        this.outStream = out;
        this.inStream = in;
    }
}

Whenever you create your streams for a client stick them in an instance of this Client class. Then you can put the Client objects in a List and iterate all you want.

for (Client client : clientList) {
    // do whatever you want with client.outStream and client.inStream
}

Now you end up with a List<Client>, which is much easier for a person to grok than a HashSet<ArrayList<Object>>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top