Każdy jest innym i nikt sobą samym.

BruceEckel.com
e.printStackTrace();
}
}
public static void main(String[] args) {
new ChatterServer();
}
} ///:~
The ChatterServer contains a single DatagramSocket for receiving messages, instead of creating one each time you’re ready to receive a new message. The single DatagramSocket can be used repeatedly. This DatagramSocket has a port number because this is the server and the client must have an exact address where it wants to send the datagram. It is given a port number but not an Internet address because it resides on “this” machine so it knows what its Internet address is (in this case, the default localhost). In the infinite while loop, the socket is told to receive( ), whereupon it blocks until a datagram shows up, and then sticks it into our designated receiver, the DatagramPacket dp. The packet is converted to a String along with information about the Internet address and socket where the packet came from. This information is displayed, and then an extra string is added to indicate that it is being echoed back from the server.
Now there’s a bit of a quandary. As you will see, there are potentially many different Internet addresses and port numbers that the messages might come from – that is, the clients can reside on any machine. (In this demonstration they all reside on the localhost, but the port number for each client is different.) To send a message back to the client that originated it, you need to know that client’s Internet address and port number. Fortunately, this information is conveniently packaged inside the DatagramPacket that sent the message, so all you have to do is pull it out using getAddress( ) and getPort( ), which are used to build the DatagramPacket echo that is sent back through the same socket that’s doing the receiving. In addition, when the socket sends the datagram, it automatically adds the Internet address and port information of this machine, so that when the client receives the message, it can use getAddress( ) and getPort( ) to find out where the datagram came from. In fact, the only time that getAddress( ) and getPort( ) don’t tell you where the datagram came from is if you create a datagram to send and you call getAddress( ) and getPort( ) before you send the datagram (in which case it tells the address and port of this machine, the one the datagram is being sent from). This is an essential part of datagrams: you don’t need to keep track of where a message came from because it’s always stored inside the datagram. In fact, the most reliable way to program is if you don’t try to keep track, but instead always extract the address and port from the datagram in question (as is done here).
To test this server, here’s a program that makes a number of clients, all of which fire datagram packets to the server and wait for the server to echo them back.
//: ChatterClient.java
// Tests the ChatterServer by starting multiple
// clients, each of which sends datagrams.
import java.lang.Thread;
import java.net.*;
import java.io.*;
public class ChatterClient extends Thread {
// Can listen & send on the same socket:
private DatagramSocket s;
private InetAddress hostAddress;
private byte[] buf = new byte[1000];
Chapter 15: Network Programming
671
private DatagramPacket dp =
new DatagramPacket(buf, buf.length);
private int id;
public ChatterClient(int identifier) {
id = identifier;
try {
// Auto-assign port number:
s = new DatagramSocket();
hostAddress =
InetAddress.getByName("localhost");
} catch(UnknownHostException e) {
System.err.println("Cannot find host");
System.exit(1);
} catch(SocketException e) {
System.err.println("Can't open socket");
e.printStackTrace();
System.exit(1);
}
System.out.println("ChatterClient starting");
}
public void run() {
try {
for(int i = 0; i < 25; i++) {
String outMessage = "Client #" +
id + ", message #" + i;
// Make and send a datagram:
s.send(Dgram.toDatagram(outMessage,
hostAddress,
ChatterServer.INPORT));
// Block until it echoes back:
s.receive(dp);
// Print out the echoed contents:
String rcvd = "Client #" + id +
", rcvd from " +
dp.getAddress() + ", " +
dp.getPort() + ": " +
Dgram.toString(dp);
System.out.println(rcvd);
}
} catch(IOException e) {
e.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++)
new ChatterClient(i).start();
}
} ///:~
ChatterClient is created as a Thread so that multiple clients can be made to bother the server. Here you can see that the receiving DatagramPacket looks just like the one used for ChatterServer. In the constructor, the DatagramSocket is created with no arguments since 672
Thinking in Java
www.BruceEckel.com