Networking API for Java

 < Day Day Up > 



Java includes a very rich set of networking APIs that operate at three layers. A standard Sockets API, an abstract set of classes for higher-level functionality, and even higher-level Application layer protocols, such as HTTP, FTP, SMTP, and Telnet, are provided.

In this chapter, we focus on the more popular classes within the java.net framework. Each class in this framework is derived from the Object class (as shown in Figure 10.1). Class DatagramSocket provides the ability to write datagram-based servers and clients (using protocol UDP). Class DatagramPacket is used by objects that use the DatagramSocket as a means to build packets complete with payload and destination address and port. Class MulticastSocket is derived from class DatagramSocket to provide multicast capabilities. InetAddress is the address class and is used to build Internet addresses. Class ServerSocket is a class that abstracts some of the server concepts for building stream socket applications. Finally, Socket provides a BSD-like Sockets API for those who desire the standard API.

click to expand
Figure 10.1: Java simplified Sockets API class hierarchy.

Sockets API Summary

We saw in Figure 10.1 that Java provides a number of classes for Sockets programming; let’s now take a brief look at the classes and methods that are available.

DatagramSocket Class

The DatagramSocket class provides the base for UDP socket classes. This class provides the set of features required to send and receive datagram packets (although not the ability to create them, more to come with DatagramPacket). Methods for the DatagramSocket class are shown in Figure 10.2.

start figure

Method

Returns

Description

DatagramSocket()

DatagramSocket

Create a new Datagram socket and bind it to an ephemeral port.

DatagramSocket( int port )

DatagramSocket

Create a new Datagram socket and bind it to the defined port.

DatagramSocket( int port, lnetAddress laddr)

DatagramSocket

Create a new Datagram socket and bind it to the defined port and local interface (laddr).

Close()

void

Close the previously “connected” Datagram socket.

connect( lnetAddress raddr, int port

void

Set the remote address association for the Datagram socket.

disconnect()

void

Remove the remote address association for the given Datagram socket.

getlnetAddress()

lnetAddress

Get the remote address association (peer) for the given Datagram socket (set via connect

getLocalAddress()

lnetAddress

Get the local address for the Datagram socket.

getPort()

int

Get the remote port to which this Datagram socket is connected (set in connect).

getLocalPort()

int

Get the local port for this Datagram socket.

getReceiveBufferSize()/setReceiveBufferSize()(SO_RCVBUF).

int/void

Get or Set the receive socket buffer size

getSendBufferSize()/(SO_SNDBUF).

int/void

Get or Set the send socket buffer size setSendBufferSize()

getSoTimeout()/setSoTimeout()for SO_TIMEOUT.

int/void

Get or set the Timeout value (in milliseconds)

receive( DatagramPacket DatagramSocket.

void

Receive a DatagramPacket through the packet)

send( DatagramPacket packet)

void

Send a DatagramPacket through the DatagramSocket.

end figure

Figure 10.2: DatagramSocket class methods. (Adapted from [Java] Java 2 Platform, Standard Edition, v1.2.2 API Specification, available online at http://java.sun.com/products/jdk/1.2/docs/api/java/net/ DatagramSocket.html.)

DatagramPacket Class

The DatagramPacket class provides the ability to create and initialize datagram packets for receipt or transmission by the DatagramSocket class. The methods provided by the DatagramPacket class are shown in Figure 10.3.

start figure

Method

Returns

Description

DatagramPacket( byte[] buf, int buflen )

DatagramPacket

Create a new Datagram socket and bind it to an ephemeral port.

DatagramPacket( byte[] buf, int buflen, lnetAddress peeraddr, int peerport )

DatagramPacket

Create a new Datagram socket and bind it to the defined port.

DatagramPacket( byte[] buf, int offset, int buflen )

DatagramPacket

Create a new Datagram socket and bind it to the defined port and local interface (laddr).

DatagramPacket( byte[] buf, int offset, int buflen, lnetAddress peeraddr, int peerport)

DatagramPacket

Close the previously “connected” Datagram socket.

getAddress()/setAddress

lnetAddress

Get or Set the IP address to which this datagram is being sent or from which it was received.

getPort()/setPort()

void

Get or Set the port to which this datagram is being sent or from which it was received.

getData()

byte[]

Get the data received (or to be sent) in this DatagramPacket.

getLength()/setLength()

int

Get or Set the length of data to be sent or which was received.

getOffset()

int

Get the offset of the data to be sent or from which was received.

setData( byte[] buf )

void

Set the data buffer for this DatagramPacket.

setData( byte[] buf, int offset, int buflen )

int/void

Sets the data buffer for this DatagramPacket.

end figure

Figure 10.3: DatagramPacket class methods. (Adapted from [Java] Java 2 Platform, Standard Edition, v1.2.2 API Specification, available online at http://java.sun.com/products/jdk/1.2/docs/api/java/net/DatagramPacket.html.)

MulticastSocket Class

The MulticastSocket class provides the an extension of the DatagramSocket class for multicast. The methods provided in the MulticastSocket class are shown in Figure 10.4.

start figure

Method

Returns

Description

DatagramPacket( byte[] buf, int buflen )

DatagramPacket

Create a new Datagram socket and bind it to an ephemeral port.

DatagramPacket( byte[] buf, int buflen, lnetAddress peeraddr, int peerport )

DatagramPacket

Create a new Datagram socket and bind it to the defined port.

DatagramPacket( byte[] buf, int offset, int buflen )

DatagramPacket

Create a new Datagram socket and bind it to the defined port and local interface (laddr).

DatagramPacket( byte[] buf, int offset, int buflen, lnetAddress peeraddr, int peerport)

DatagramPacket

Close the previously “connected” Datagram socket.

getAddress()/setAddress

lnetAddress

Get or Set the IP address to which this datagram is being sent or from which it was received.

getPort()/setPort()

void

Get or Set the port to which this datagram is being sent or from which it was received.

getData()

byte[]

Get the data received (or to be sent) in this DatagramPacket.

getLength()/setLength()

int

Get or Set the length of data to be sent or which was received.

getOffset()

int

Get the offset of the data to be sent or from which was received.

setData( byte[] buf )

void

Set the data buffer for this DatagramPacket.

setData( byte[] buf, int offset, int buflen )

int/void

Sets the data buffer for this DatagramPacket.

end figure

Figure 10.4: MulticastSocket class methods. (Adapted from [Java] Java 2 Platform, Standard Edition, v1.2.2 API Specification, available online at http://java.sun.com/products/jdk/1.2/docs/api/java/net/MulticastSocket.html.)

InetAddress Class

The InetAddress class provides a small number of methods to deal with domain names, name resolution, and testing addresses. The methods provided in the InetAddress class are shown in Figure 10.5.

start figure

Method

Returns

Description

equals( Object obj )

boolean

Compares two lnetAddress objects.

getAddress()

byte[]

Return the raw IP address for the lnetAddress object.

getAllByName( String host )

lnetAddress[]

Return the IP addresses for the specified host.

getByName( String Host )

lnetAddress

Return the IP address for the specified host.

getHostAddress()

String

Return the dotted-notation String.

getHostName()

String

Return the hostname for the current host.

getLocalHost

lnetAddress

Return the local host address.

isMulticastAddress()

boolean

Check if the lnetAddress is a multicast address.

end figure

Figure 10.5: InetAddress class methods. (Adapted from [Java] Java 2 Platform, Standard Edition, v1.2.2 API Specification, available online at http://java.sun.com/products/jdk/1.2/docs/api/java/net/ InetAddress.html.)

Socket Class

The Socket class provides a set of methods for the creation of client Sockets applications. These methods are shown in Figure 10.6.

start figure

Method

Returns

Description

Socket()

Socket

Creates an unconnected socket.

Socket( lnetAddress raddr, int rport )

Socket

Create a socket and connect it to the lnetAddress/port.

Socket( lnetAddress raddr, int rport, lnetAddress laddr, int lport )

Socket

Create a socket and connect it to raddr/rport, binding it locally to laddr/lport.

Socket( String host, int port )

Socket

Create a socket and connect it to the named host and port.

close()

void

Close the socket

getlnetAddress()

lnetAddress

Return the peer address to which this socket is connected.

getLocalAddress

lnetAddress

Return the local address from which this is connected.

getLocalPort()/getPort()

int/int

Get the Local or Remote port.

getInputStream/getOutputStream

InputStream/ OutputStream

Convert the IP address to a dotted-notation String.

getReceiveBufferSize()/setReceiveBufferSize()

int/void

Gets or Sets the SO_RCVBUF socket option.

getSendBufferSize()/setSendBufferSize()

int/void

Gets or Sets the SO_SNDBUF socket option.

getSoLinger()/setSoLinger()

int/void

Gets or Sets the SO_LINGER socket option.

getPcpNoDelay()/setTcpNoDelay()

boolean/void

Gets or Sets the TCP_NODELAY socket option.

getSoTimeout()/setSoTimeout()

int/void

Gets or Sets the SO_TIMEOUT socket option.

end figure

Figure 10.6: Socket class methods. (Adapted from [Java] Java 2 Platform, Standard Edition, v1.2.2 API Specification, available online at http://java.sun.com/products/jdk/1.2/docs/api/java/net/ServerSocket.html.)

ServerSocket Class

Finally, the ServerSocket class provides a number of methods specifically for the creation of TCP server sockets. These methods are shown in Figure 10.7.

start figure

ServerSocket( int port )

Socket

Create a server socket on the specified port.

ServerSocket( int port, int backlog )

Socket

Create a server socket on the specified port with the specified backlog.

ServerSocket( int port, int backlog, lnet Address laddr )

Socket

Create a socket and connect it to raddr/rport, binding locally to laddr/lport.

accept()

Socket

Accept a new client connection.

close()

void

Close the socket.

getlnetAddress()

lnetAddress

Return the local address for this socket.

getLocalPort

int

Return the port on which this port is listening.

getSoTimeout()/setSoTimeout()

int/void

Gets or Sets the SO_TIMEOUT socket option.

end figure

Figure 10.7: class methods. (Adapted from [Java] Java 2 Platform, Standard Edition, v1.2.2 API Specification, available online at http://java.sun.com/products/jdk/1.2/docs/api/java/net/ServerSocket.html.)

Sockets API Discussion

Let’s now look at how the Java networking API is used. We’ll exercise many of the methods shown in the previous class method figures, including how using methods from the ServerSocket can simplify the development of server Sockets programming.

Creating and Destroying Sockets

As with any sockets-based application, the creation of a socket is the first step before communication may occur. Java provides a number of methods for socket creation, depending upon the type of socket needed by the developer. We look at the primitive example first, and then move on to Java’s more expressive methods that can simplify application development.

Note 

All of the methods discussed in this section require that the application developer make the networking classes visible. At the beginning of the Java application, a line specifying, import java.net.*; must be present.

The Socket class provides the primitive standard socket function that is most familiar to C language programmers. The Socket class methods can be used to create stream (TCP) client sockets.

Socket sock = Socket( "192.168.1.1", 25 );

The Socket constructor of the Socket class not only creates the client TCP socket, but also connects it to the remote peer defined by the arguments. In this case, upon successful completion of the Socket constructor, sock will be connected to host “192.168.1.1” and port 25. We could also use a variant of the Socket constructor to create a socket, connect it to a remote host, and port and bind it to a local address and port. This is accomplished with:

Socket sock = Socket( "192.168.1.1",  // Remote Host                         25,             // Remote Port                         "10.0.0.1",     // Local Interface                         25000 );        // Local Port

To create a TCP server socket, the following can be done with ServerSocket:

ServerSocket sockserv = ServerSocket( 8080 );

which creates a TCP server socket and binds it to the local port 8080. To bind not only to a local port, but also to a local interface, we could do the following:

InetAddress laddr = InetAddress.getByName( "10.0.0.2" ); ServerSocket sockserv = ServerSocket( 8080, 5, laddr );

This first creates an address structure (for the interface represented by IP address “10.0.0.2”) and stores it in laddr. Next, the server socket is created with the ServerSocket constructor with port 8080, a backlog of 5 connections, and the previously created address object, laddr.

To create a datagram socket, we use the DatagramSocket constructor:

DatagramSocket dgramsock = DatagramSocket();

We create a datagram socket for server connections, binding it to address 23000 with:

DatagramSocket dgramsock = DatagramSocket( 23000 );

Finally, we could bind not only to a port, but also to a local interface using the following:

InetAddress laddr = InetAddress.getByName( "10.0.0.2" ); ServerSocket sockserv = DatagramSocket( 8080, laddr );

Multicast sockets are treated differently in Java than in most other languages, where they are simply derived from datagram sockets. The MulticastSocket class is derived from DatagramSocket, but must be used if multicast communication is desired for the socket. The following two examples illustrate the creation of a MulticastSocket and the creation of a MulticastSocket that will be bound to the local port, 45000.

MulticastSocket mcsock = MulticastSocket(); MulticastSocket mcsock = MulticastSocket( 45000 ); 

When we’re finished with a socket, we must close it. To close a previously created socket, sock, we use the close method. The close method is part of all of the previously discussed classes (except for MulticastSocket, whose close method is derived from the DatagramSocket).

sock.close();

After the close method is called, no further communication is possible with this socket.

Any data queued for transmission would be given some amount of time to be sent before the connection physically closes.

Socket Addresses

Unlike C, Java has no sockaddr_in structure, but instead a simpler object that represents only the address and not the port. Dealing with addresses in Java is much simpler than in C, because methods exist in many of the classes to both set and extract addresses and ports for sockets.

To create an address object, we use the InetAddress class. To create an InetAddress object from a host name or dotted-notation IP address string, the getByName method can be used (illustrated as follows):

try {     InetAddress adrs =       InetAddress.getByName( "www.microsoft.com" );     System.out.println("Address is " + adrs.toString() );   }   catch (UnknownHostException e )   {     System.out.println("Caught exception " + e );   }

This example illustrates not only the getByName method of the InetAddress class, but also some additional attributes of the Java language. Rather than return an error, the getByName has the potential to throw an exception. Exceptions are not returned, but instead raised at a higher level and caught within the calling method with the catch statement. In the previous example, the getByName method can throw the UnknownHostException, which is caught and a message emitted to standard-out (System.out). If the getByName method succeeds, we’ll continue within the try statement and emit the address to standard-out using the toString method.

The getByName method is also used with dotted-notation IP address strings:

try {     InetAddress adrs =       InetAddress.getByName( "10.0.0.1" );     System.out.println("Address is " + adrs.toString() );   }   catch (UnknownHostException e )   {     System.out.println("Caught exception " + e );   }

Socket Primitives

In this section, we look at a number of other important socket control methods using the standard Socket and SocketServer classes. We also investigate the variety of ways that the same results can be achieved using different Java classes.

Bind

The bind method traditionally provides a local naming capability to a socket. This can be used to name either client or server sockets, but is used most often in the server case. The bind method is implicit in a number of Java classes, such as the ServerSocket constructor:

  InetAddress laddr = InetAddress.getByName( "10.0.0.1" );   ServerSocket servsock = ServerSocket( 8080 ); // or ServerSocket servsock = ServerSocket( ladrs, 8080 );

The ServerSocket constructor is used to not only create the server socket, but also to bind it to a local address. In the first case, we bind only to port 8080 and all available interfaces (INADDR_ANY). In the second case, we bind to a specific interface (represented by IP address “10.0.0.1”) and port 8080.

The bind can also be used to bind a client socket to a local address. The Socket constructor of the Socket class (for client sockets) provides a special constructor to not only bind, but also to connect, as is illustrated:

InetAddress local_addr =                 InetAddress.getByName( "10.0.0.1" ); InetAddress remote_addr =                 InetAddress.getByName( "192.168.1.1" ); Socket clisock = Socket( remote_addr, 8080,                            local_addr, 52000 );

The bind construct can also be done automatically with the DatagramSocket constructor of the DatagramSocket class. Two variations are provided, just as is done with the ServerSocket:

InetAddress laddr = InetAddress.getByName( "10.0.0.1" ); DatagramSocket servsock = DatagramSocket( 8080 ); // or DatagramSocket servsock = DatagramSocket( 8080, ladrs );

In the first example, the datagram socket is bound to port 8080 and all interfaces, while the second example illustrates not only binding to port 8080, but also to the local interface identified by the address “10.0.0.1.”

Listen

Before a traditional server socket can accept incoming client connections, it must call the listen method to declare this willingness. The listen method is not provided in the Java networking API, but is instead implicit in the server socket setup. For example,

InetAddress laddr = InetAddress.getByName( "10.0.0.1" ); int port = 8080; int backlog = 5; ServerSocket servsock =                 ServerSocket( port, backlog, laddr ); 

provides not only socket creation and interface binding, but also a call to listen to start the server socket up for incoming connections. The backlog parameter is traditionally used for the listen call, but is passed here to the ServerSocket constructor to set up the connection queue backlog limit.

Accept

The accept method is the final call made by servers to accept incoming client connections. In Java, this method is provided in the ServerSocket class and returns a new client Socket object.

InetAddress laddr = InetAddress.getByName( "192.168.110.5" ); int port = 8080; int backlog = 5; ServerSocket servsock =                 ServerSocket( port, backlog, laddr ); Socket clisock = servsock.accept();

The accept method in the ServerSocket class accepts a new client connection and returns a client Socket object. This new client socket can then be used for further communication with the client’s peer.

Connect

The connect method is used by client Sockets applications to connect to a server. In Java, the connect method is implicit in the creation of client sockets using the Socket class. Consider the following example of creating a client socket and connecting it to IP address “192.168.1.2”, port 13.

InetAddress remote_addr =                 InetAddress.getByName( "192.168.1.2" ); int port = 13; Socket clisock = Socket( remote_addr, port );

Upon completion of the Socket constructor, the client socket is connected to the defined remote address and port. Note that the exception handling is not shown here (try / catch).

Recall that datagram sockets can also be connected. This means that the peer address is automatically defined and packets may only be sent to that address. Normally, the peer address must be defined for all datagrams sent from the socket. Creating a connected datagram socket is illustrated as follows:

InetAddress raddr =                 InetAddress.getByName( "192.168.1.2" ); int port = 450; DatagramSocket dgramcli =                    DatagramSocket( port, raddr );

Upon completion of the DatagramSocket constructor, a new datagram socket is created with the peer information cached with the socket. No synchronization is performed with the peer, only the peer address and port configured with the socket. To remove the association of the peer address, the disconnect call can be performed:

dgramcli.disconnect();

Upon completion, the association is removed and datagrams can henceforth be sent to any remote peer.

Sockets I/O

A variety of methods exists to read data from a socket or write data to a socket. Some methods are class specific, and others inherit methods from other classes (such as input and output streams). First, we look at reading and writing from connected sockets and then investigate unconnected (datagram-specific) socket communication.

A number of methods are provided to communicate through a socket. Some of the functions include recv and send, though these are commonly restricted to datagram sockets. We look at examples of each of these functions in the following sections. Other techniques, such as InputStream/OutputStream methods can also be used, and we investigate examples of their use as well.

Stream Sockets

Stream sockets utilize the stream concept of Java IO. This permits a simple layering of stream filters over a socket for read and write purposes. Let’s look at a simple example of this concept before moving on to our Sockets examples.

Consider the operation of reading from a file. We’ll use a file stream as our inner filter, but then layer a buffered input stream as the outer filter. Buffered streams are typically more efficient because the stream is buffered to reduce the number of physical accesses of the file.

FileInputStream file = new                    FileInputStream( "file.dat" ); BufferedInputStream bis = new                    BufferedInputStream( file ); int ret = 0; // do {       ret = buff.read(); } while (ret != -1); buff.close();

In this example, we open a FileInputStream on a file called file.dat. Next, we lay a BufferedInputStream over our FileInputStream to change the mechanism for reading the file. In the simple loop, we read the number of characters that are available until the end of file is reached, at which time we close the stream.

Java provides a variety of stream concepts for data input and output. These include Pipes (to channel data from one thread to another), Pushback (to permit peeking at the data, putting it back if necessary), Buffered (to make physical I/O more efficient), LineNumber (to help keep track of line numbers while reading), and many others.

Let’s now look at a few examples of stream sockets utilizing Java’s stream I/O concepts. In the first example, we’ll illustrate the use of the PrintWriter stream, which provides very convenient methods for emitting data through a stream.

Socket clisock; PrintWriter output; clisock = socket(); ... output = new PrintWriter( clisock.getOutputStream(), true ); ... output.println( "Hello!" );

In this simple example, a client socket is created, and after connection, a PrintWriter stream is created to provide a means to emit data through the socket. Note that in order to create the PrintWriter stream object, we must identify the output stream for the socket. To do this, we use the getOutputStream method for the specific socket, which is passed anonymously to the PrintWriter method. The true flag defines that we desire autoflush for data written to the stream. The PrintWriter stream is identified by the object output, and in the last line, we see an example of a common println to emit a string through the socket.

Let’s now look at a simple example for reading from a socket. In this example, we use the BufferedReader stream class, which can make socket reads more efficient, and we wrap the BufferedReader over the socket’s input stream.

String line; sock = new Socket(); ... input = new BufferedReader(                 new InputStreamReader(                       sock.getInputStream() ) ); line = input.readLine(); System.out.println( line );

In this example, we create a client socket called sock. To create a BufferedReader stream, we must also create an InputStreamReader, which is done anonymously over the socket’s input stream (retrieved using the getInputStream method). With our new BufferedReader stream, we can perform very simple line-oriented operations such as readLine to retrieve a single line of text from the socket. This line, in the example, is simply emitted to standard-out.

These two examples should illustrate the power of Java’s stream concept. In essence, the mechanism allows the transformation of an I/O channel to extend the types of operations that can be performed on it.

Datagram Sockets

Because datagram sockets are not stream-related, a different set of mechanisms exists to read and write datagram packets from and to the network. In fact, the construction of datagram packets uses a special class called DatagramPacket, which identifies not only the payload of the packet, but also the destination address and port information.

Let’s look at a datagram server and client that provide the echo functionality illustrated by alternative languages in other chapters. We omit the try/catch elements of the source to increase its readability. Our datagram server takes on a slightly different form:

DatagramSocket socket = new DatagramSocket( 45000 ); ... // Construct a packet for receiving datagrams. byte[] buffer = new byte[100]; DatagramPacket srcpkt = new DatagramPacket( buffer, 100 ); // Receive a datagram packet from the peer. socket.receive( packet ); // Get the IP address and port from the source packet. InetAddress peeradrs = packet.getAddress(); int peerport = packet.getPort(); // Construct a new datagram packet using the source // packet's payload, and source address and port. DatagramPacket destpkt = new     DatagramPacket( srcpkt.getData(),                     srcpkt.getLength(),                     peeradrs, peerport ); // Send the new packet back to the peer. socket.send( destpkt );

In this example, we create our DatagramSocket and then a DatagramPacket (srcpkt) that will be used to receive a datagram through the socket. We’ll accept at most a datagram with 100 octets. Next, we call the receive method for the socket object to receive the datagram. Upon receiving the datagram, we extract the source IP address from the packet using the getAddress method and the source port is extracted with getPort. We use the source address and port in the construction of the new datagram packet that we’ll send back to the peer.

We create destpkt, which is our response DatagramPacket, and provide not only the source address and port, but also the payload using the getData() method and the length of the payload with the getLength() method. Finally, the new DatagramPacket is sent to the peer (source of the original datagram) using the send method of the socket object.

As is illustrated in this example, working with datagrams in Java is slightly more involved than most other languages in that the packet structure itself is another object with its own set of methods and constructors.

Socket Options

Socket options permit an application to change some of the modifiable behaviors of sockets and the methods that manipulate them. For example, an application can modify the sizes of the send or receive socket buffers or the size of the maximum segment used by the TCP layer for a given socket.

Socket options within Java are easier than that provided to the C programmer. The socket options that are available utilize class methods to set or read the parameter for the given socket. Therefore, rather than call the setsockopt or getsockopt with a void pointer element to a structure, methods can be simply called to manipulate the options for a given socket.

As a first example, let’s say that we want to identify the size of the receive buffer for a given socket. This can be done with the following code segment:

import java.net.*; // Create a socket and connect it to a server. InetAddress adrs = InetAddress.getByName( "192.168.1.1" ); Socket sock = Socket( adrs, 80 ); int receiveBuffer = sock.getReceiveBufferSize();

First, we create our address object, which represents the server to which we’re going to connect (“192.168.1.1”). Next, we create our client socket using the Socket constructor of the Socket class. Within the context of this method, we’ll be connected to the remote server. Finally, we retrieve the size of the socket receive buffer (traditionally, SO_RCVBUF) and store it into receiveBuffer using the getReceiveBufferSize method of the Socket class.

Now, let’s look at how an option is set for a given socket, specifically, the linger option. Socket linger allows us to change the behavior of a stream socket when the socket is closed and data is remaining to be sent. After close is called, any data remaining will attempt to be sent for some amount of time. If after some duration, the data cannot be sent, then the data to be sent is abandoned. The time after the close to when the data is removed from the send queue is defined as the linger time. In Java, this is yet another method called setSoLinger. Rather than the typical linger structure used in C and other languages, the setSoLinger method simply takes two options for the enable and linger time, as illustrated:

import java.net.*; // Create a socket and connect it to a server. InetAddress adrs = InetAddress.getByName( "192.168.1.1" ); Socket sock = Socket( adrs, 80 ); sock.setSoLinger( true, 10 );

The first argument to setSoLinger is the enable for the linger option (in this case, true represents enabled, false is disabled). The linger time is measured in seconds. In the example, we’re enabling linger and setting the linger value to 10 seconds. We could read back what was configured by:

int linger = sock.getSoLinger()

A return of –1 means that the option is disabled. Any other value means that the linger option is enabled, and the value represents the number of seconds configured for linger.

Other Miscellaneous Functions

Let’s now look at a few miscellaneous functions from the various Sockets APIs and the capabilities they provide. The first methods that we discuss provide information about the current host. Method getHostName (of the InetAddress class) returns the string name of the host:

String hoststr; try {     InetAddress myAddr =         InetAddress.getByName( "192.168.1.1" );         hoststr = myAddr.getHostName();         System.out.println( "Hostname is " + hoststr );     } catch ( UnknownHostException e ) {}

We first get an InetAddress (our raw address format for Java) given a string IP address in dotted notation. Next, we use the getHostName method on that InetAddress object to get the host name. This is then emitted to standard-out with System.out.println.

The DNS resolver permits us to resolve an IP address to a host name, or vice versa. Method getHostAddress provides address resolution given a name, for example:

String adrsstr; try {     InetAddress myAddr =         InetAddress.getByName( "www.gnu.org" );         adrsstr = myAddr.getHostAddress();         System.out.println( "Host Address is " + adrsstr );     } catch ( UnknownHostException e ) {}

where the response is a string of the IP address in dotted notation.

We can also identify the address of the current host, and its host name with the following Java snippet:

String hoststr String adrsstr; try {     // First, create our InetAddress object     InetAddress myAddr = InetAddress.getLocalHost();         // Now use this object to retrieve the address and name         adrsstr = myAddr.getHostAddress();         hoststr = myAddr.getHostName();         System.out.println( "Hostname is " + hoststr );         System.out.println( "Host Address is " + adrsstr );     } catch ( UnknownHostException e ) {}

Additionally, given an InetAddress object, we can always convert this to a string for display using the toString method of the InetAddress class:

InetAddress myAddr = InetAddress.getLocalHost(); System.out.println( "Address is " + myAddr.toString() );

which provides both the host name and dotted-notation IP address as follows:

Address is www.microsoft.com/207.46.134.190

Finally, Java also provides a method to retrieve all of the known IP addresses for a given host. The following snippet illustrates this:

try {     // First, create our InetAddress object     InetAddress[] addrs = InetAddress.getAllByName( "www.microsoft.com" );         int i;         for (i = 0 ; i < addrs.length ; i++ ) {             System.out.println( "Address : " +                 addrs[i].toString();         }     } catch ( UnknownHostException e ) {}

We first create our InetAddress[] array object and use the getAllByName method to load it with all available addresses for the domain name. We then loop through the number of addresses (identified with the length attribute of the addrs variable) emitting the addresses with the toString method.



 < Day Day Up > 



BSD Sockets Programming from a Multi-Language Perspective
Network Programming for Microsoft Windows , Second Edition (Microsoft Programming Series)
ISBN: 1584502681
EAN: 2147483647
Year: 2003
Pages: 225
Authors: Jim Ohlund

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net