Customizing Socket Behavior Sockets

response.write_mainPage; response.flush ; } Figur e 2- 3 is a screenshot of our web server in action, handling a request made using Netscape Navigator 6. Figure 2-3. The WebServer application Note the use of metadata here. When a web browser asks a web server for a page, it sends information in addition to what page it wants™a description of how the page should be sent and what the page should contain. In the previous example, the web browser stated what protocol is being used HTTP 1.0, what type of web browser it is Netscape 6, what sort of response is desired indicated by the two Accept lines, and the site that referred to the page being requested i.e., if you clicked on a link to request the page, the page you were on is passed to the web server as well.

2.4 Customizing Socket Behavior

In addition to the basic methods for creating connections and sending data, the Socket class defines a number of methods that enable you to set some fairly standard socket parameters. Setting these standard socket parameters wont change how the rest your code interacts with the socket. However, it will change the sockets network behavior. The methods, paired along get set lines, are: public boolean getKeepAlive public void setKeepAliveboolean on public int getReceiveBufferSize public void setReceiveBufferSizeint size public int getSendBufferSize public void setSendBufferSizeint size public int getSoLinger public void setSoLingerboolean on, int linger public int getSoTimeout public void setSoTimeoutint timeout public boolean getTcpNoDelay public void setTcpNoDelayboolean on In the rest of this section, we discuss these parameters in more detail: public boolean getKeepAlive public void setKeepAliveboolean on One problem with distributed applications is that if no data arrives over a long period of time, you need to wonder why. On one hand, it could be that the other program just hasnt had any information to send recently. On the other hand, the other program could have crashed. TCP handles this problem by allowing you to send an Are you still alive? message every so often to quiet connections. The way to do this is to call setKeepAlive with a value of true . Note that you dont need to worry about one side of the connection dying when you use RMI. The distributed garbage collector and the leasing mechanism which well discuss in Chapt er 16 handle this problem automatically. public int getReceiveBufferSize public void setReceiveBufferSizeint size public int getSendBufferSize public void setSendBufferSizeint size The setReceiveBufferSize and setSendBufferSize methods attempt to set the size of the buffers used by the underlying protocol. Theyre not guaranteed to work; instead they are officially documented as methods that give hints to the operating system. However, the operating system is free to ignore these hints if it wants to. The basic trade-off is this: assuming the TcpNoDelay property is set to false , then using larger buffers mean larger chunks of data are sent. This results in a more efficient use of network bandwidth, as fewer headers get sent and fewer headers have to be parsed along the way. On the other hand, using larger buffers often means that there is a longer wait before data is sent, which may cause overall application performance to lag. public int getSoLinger public void setSoLingerboolean on, int linger setSoLinger and getSoLinger refer to how long the system will try to send information after a socket has been closed. Recall that under TCPIPs buffering stategy, information is often held at the senders side of the wire until the recipient is ready to handle it. Suppose that an application opened a socket, wrote some data to the socket, and immediately closed the socket. By default, the close method will return immediately, and the operating system will still attempt to send the data on its own. If the setSoLinger method is passed in a boolean of false , it will continue to behave this way. If the method is passed in a boolean of true , the close method of the socket will block the specifed number of seconds an integer, waiting for the operating system to transmit the data. If the time expires, the method returns, and the operating system does not transmit the data. The maximum linger time is 65,535 seconds, even though you can pass in a much larger integer; a value of -1 means the operating system will keep trying forever. The platform default is generally the best option. public int getSoTimeout public void setSoTimeoutint timeout When you try to read data from a sockets input stream, the read methods all block while they wait for data. The timeout simply states how long they should wait before throwing an exception. A value of 0 means the socket will wait forever; this is the default behavior. public boolean getTcpNoDelay public void setTcpNoDelayboolean on Recall that one of the things TCP adds to IP is buffer management. The program that receives data has a fixed-length buffer in which to receive information and must tell the sender when buffer space becomes available. If buffer space becomes available at a very slow rate e.g., if data is being removed from the buffer very slowly, then its possible that the recipient will send messages such as, Send me three more bytes of data. Ive got the buffer space for it now. This behavior, which results in a horrible waste of bandwidth, is called the silly-window problem. TCP usually avoids the silly window problem by grouping information before sending it. That is, rather than sending small amounts of information repeatedly, TCP usually waits until a large amount of information is available and sends it together. The setTCPNoDelay method enables you to turn this behavior off. An argument of true will force the sockets layer to send information as soon as it becomes available.

2.5 Special-Purpose Sockets