Public Class Datagramsocket Extends Object
Public Class Datagramsocket Extends Object
The Constructors
The DatagramSocket class has three constructors that are used in different situations, much
like the DatagramPacket class. The first constructor opens a datagram socket on an
anonymous local port. The second constructor opens a datagram socket on a well-known
local port that listens to all local network interfaces. The third constructor opens a
datagram socket on a well-known local port on a specific network interface. All three
constructors deal only with the local address and port. The remote address and port are
stored in the DatagramPacket, not the DatagramSocket. Indeed, one DatagramSocket can send
and receive datagrams from multiple remote hosts and ports.
public DatagramSocket( ) throws SocketException
This constructor creates a socket that is bound to an anonymous port. For example:
try {
DatagramSocket client = new DatagramSocket( );
// send packets...
}
catch (SocketException e) {
System.err.println(e);
}
You would use this constructor in a client that initiates a conversation with a server. In
this scenario, you don't care what port you are using, because the server will send its
response to the port from which the datagram originated. Letting the system assign a port
means that you don't have to worry about finding an unused port. If for some reason you
need to know the local port, you can find out with the getLocalPort( ) method described
later in this chapter.
The same socket may be used to receive the datagrams that a server sends back to it. A
SocketException is thrown if the socket can't be created. It's unusual for this constructor to
throw an exception; it's hard to imagine situations in which the socket could not be
opened, since the system gets to choose the local port.
public DatagramSocket(int port) throws SocketException
This constructor creates a socket that listens for incoming datagrams on a specific port,
specified by the port argument. You would use this constructor to write a server that has
to listen on a well-known port; if servers listened on anonymous ports, clients would not
be able to contact them. A SocketException is thrown if the socket can't be created. There
are two common reasons for the constructor to fail: the specified port is already occupied,
or you are trying to connect to a port below 1,024 and you don't have sufficient privileges
(i.e., you are not root on a Unix system; for better or worse, other platforms allow anyone
to connect to low-numbered ports). TCP ports and UDP ports are not related. Two
unrelated servers or clients can use the same port number if one uses UDP and the other
uses TCP. Example 13.2 is a port scanner that looks for UDP ports in use on the local
host. It decides that the port is in use if the DatagramSocket constructor throws an
exception. As written, it looks at ports from 1,024 up to avoid Unix's requirement that it
run as root to bind to ports below 1,024. You can easily extend it to check ports below
1,024, however, if you have root access or are running it on Windows or a Mac.
The speed at which UDPPortScanner runs depends strongly on the speed of your
machine and its UDP implementation. I've clocked Example 13.2 at as little as two
minutes on a moderately powered SPARCstation and as long as an hour on a
PowerBook 5300. Here are the results from one SPARCstation: The high-numbered
UDP ports in the 30,000 range are Remote Procedure Call (RPC) services. Aside from
RPC, some common protocols that use UDP are NFS, TFTP, and FSP. It's much harder
to scan UDP ports on a remote system than to scan for remote TCP ports. Whereas there's
always some indication that your TCP packet has been received by a listening port
regardless of application layer protocol, UDP provides no such guarantees. To determine
that a UDP server is listening, you have to send it a packet it will recognize and respond
to.
Managing Connections
Unlike TCP sockets, datagram sockets aren't very picky about whom they'll talk to. In
fact, by default they'll talk to anyone. But this is often not what you want. For instance,
applets are only allowed to send datagrams to and receive datagrams from the applet host.
An NFS or FSP client should accept packets only from the server it's talking to. A
networked game should listen to datagrams only from the people playing the game. In
Java 1.1, programs must manually check the source addresses and ports of the hosts
sending them data to make sure they're who they should be. However, Java 1.2 adds four
methods that let you choose which host you can send datagrams to and receive datagrams
from, while rejecting all others' packets.