This is a bit of a "further down the track now" extension to a question I asked a while ago... I have a better understanding of sockets now, and have some working code but need to improve it...
Ok, so I have currently got UDP multicasting working to send short strings of text from a Java 'server' application to several Android phones (which will potentially become several hundred Android phones). This works fine most of the time, but it does tend to lose the odd string on the odd phone, and randomly it will just go total loss for a short period and nothing will get through to any of them, which can be a little frustrating.
Since, as I understand, there is no way to broadcast on TCP - my idea is to have the phones initially 'connect' to the server app using a ServerSocket. This will do nothing more than harvest client IP addresses which are to be stored in a Set<InetAddress>
called clients. Then I will want to iterate over these addresses and send the string to each phone individually - but I don't want to block the code, nor do I want to spend forever waiting for sends to occur if, say, the phone has gone to sleep and can't / won't accept connections. The information will need to get to all phones within a few seconds of starting to send (even with 2-300 clients).
My initial code is below, and the questions I have regarding it are:
- Is this code in one thread enough?
- Would a modern CPU make good use of several threads with the address set split evenly amongst them (say 4 threads?)
- Is it (as I believe) a bad idea to spin every connection/send off in its own thread?
- Does setting the socket timeout allow the thread to work through its list faster? Or will this cause problems?
- If socket timeout setting is a good idea, then what is a sensible time? Or do I need to just test to get this right?
Thanks in advance for any help you guys can provide...
for (InetAddress client : clients) {
try {
Socket sendQuestionSocket = new Socket(client, portSend);
// Theory: 50 milliseconds is enough to connect, and could allow 200 clients
// to get their questions in around 10 seconds. Maybe?
sendQuestionSocket.setSoTimeout(50);
PrintWriter outStream = new PrintWriter(sendQuestionSocket.getOutputStream());
outStream.println(question.toString());
outStream.flush(); // Do I need this line?
sendQuestionSocket.close();
outStream.close();
} catch (InterruptedIOException e) {
logger.log(Level.WARNING, "Couldn't connect in time... passing this one over");
e.printStackTrace();
} catch (UnknownHostException e) {
logger.log(Level.SEVERE, "Unable to find that client");
e.printStackTrace();
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to create question sending port");
e.printStackTrace();
}
}