All About Datagrams |
In addition toDatagramSocket
, which lets programs send packets to one another, java.net includes a class calledMulticastSocket
. This kind of socket is used on the client-side to listen for packets that the server broadcasts to multiple clients.Let's rewrite the quote server so that it broadcasts
DatagramPacket
s to multiple recipients. Instead of sending quotes to a specific client that makes a request, the new server now needs to broadcast quotes at a regular interval. The client needs to be modifies sot that it passively listens for quotes and does so on aMulticastSocket
.This example is comprised of three classes which are modifications of the three classes from the previous example:
MulticastServer
,MulticastServerThread
, andMulticastClient
. This discussion highlights the interesting parts of these classes.Here is the new version of the server's main program. The differences between this code and the previous version,
QuoteServer
, are shown in bold:Basically, the server got a new name and creates aimport java.io.*; public class MulticastServer { public static void main(String[] args) throws IOException { new MulticastServerThread().start(); } }MulticastServerThread
instead of aQuoteServerThread
. Now let's look at theMulticastServerThread
which contains the heart of the server. Here's its class declaration:We've made this class a subclass ofpublic class MulticastServerThread extends QuoteServerThread { ... }QuoteServerThread
so that it can use the constructor, and inherit some member variable and thegetNextQuote
method. Recall thatQuoteServerThread
creates aDatagramSocket
bound to port 4445 and opens the quote file. TheDatagramSocket
's port number doesn't actually matter in this example because the client never send anything to the server.The only method explicitly implemented in
MulticastServerThread
is itsrun
method. The differences between thisrun
method and the one inQuoteServerThread
are shown in bold:The interesting change is how thepublic void run() { while (moreQuotes) { try { byte[] buf new byte[256]; // don't wait for request...just send a quote String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes(); InetAddress group = InetAddress.getByName( "230.0.0.1"); DatagramPacket packet; packet = new DatagramPacket(buf, buf.length, group, 4446); socket.send(packet); try { sleep((long)Math.random() * FIVE_SECONDS); } catch (InterruptedException e) { } } catch (IOException e) { e.printStackTrace(); moreQuotes = false; } } socket.close(); }DatagramPacket
is constructed, in particular, theInetAddress
and port used to construct theDatagramPacket
. Recall that the previous example retrieved theInetAddress
and port number from the packet sent to the server from the client. This was because the server needed to reply directly to the client. Now, the server needs to address multiple clients. So this time both theInetAddress
and the port number are hard-coded.The hard-coded port number is 4446 (the client must have a
MulticastSocket
bound to this port). The hard-codedInetAddress
of theDatagramPacket
is "230.0.0.1" and is a group identifier (rather than the Internet address of the machine on which a single client is running). This particular address was arbitrarily chosen from the reserved for this purpose.Created in this way, the
DatagramPacket
is destined for all clients listening to port number 4446 who are member of the "230.0.0.1" group.To listen to port number 4446, the new client program just created its
MulticastSocket
with that port number. To become a member of the "230.0.0.1" group, the client calls theMulticastSocket
'sjoinGroup
method with theInetAddress
that identifies the group. Now, the client is set up to receiveDatagramPacket
s destined for the port and group specified. Here's the relevant code from the new client program (which was also rewritten to passively receive quotes rather than actively request them). The bold statements are the ones that interact with theMulticastSocket
:Notice that the server uses aMulticastSocket socket = new MulticastSocket(4446); InetAddress group = InetAddress.getByName("230.0.0.1"); socket.joinGroup(group); DatagramPacket packet; for (int i = 0; i < 5; i++) { byte[] buf = new byte[256]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData()); System.out.println("Quote of the Moment: " + received); } socket.leaveGroup(group); socket.close();DatagramSocket
to broadcast packet received by the client over aMulticastSocket
. Alternatively, it could have used aMulticastSocket
. The socket used by the server to send theDatagramPacket
is not important. What's important when broadcasting packets is the addressing information contained in theDatagramPacket
, and the socket used by the client to listen for it
Try this: Run theMulticastServer
and several clients. Watch how the clients all get the same quotes.
All About Datagrams |