Java Reference
In-Depth Information
byte [] data = Files . readAllBytes ( file );
ByteBuffer input = ByteBuffer . wrap ( data );
// set the port to listen on
int port ;
try {
port = Integer . parseInt ( args [ 1 ]);
if ( port < 1 || port > 65535 ) port = 80 ;
} catch ( RuntimeException ex ) {
port = 80 ;
}
String encoding = "UTF-8" ;
if ( args . length > 2 ) encoding = args [ 2 ];
NonblockingSingleFileHTTPServer server
= new NonblockingSingleFileHTTPServer (
input , encoding , contentType , port );
server . run ();
} catch ( IOException ex ) {
System . err . println ( ex );
}
}
}
The constructors set up the data to be sent along with an HTTP header that includes
information about content length and content encoding. The header and the body of
the response are stored in a single ByteBuffer so that they can be blasted to clients very
quickly. However, although all clients receive the same content, they may not receive it
at the same time. Different parallel clients will be at different locations in the file. This
is why we duplicate the buffer, so each channel has its own buffer. The overhead is small
because all channels do share the same content. They just have different indexes into
that content.
All incoming connections are handled by a single Selector in the run() method. The
initial setup here is very similar to the earlier chargen server. The run() method opens
a ServerSocketChannel and binds it to the specified port. Then it creates the Selec
tor and registers it with the ServerSocketChannel . When a SocketChannel is accepted,
the same Selector object is registered with it. Initially it's registered for reading because
the HTTP protocol requires the client to send a request before the server responds.
The response to a read is simplistic. The program reads as many bytes of input as it can
up to 4K. Then it resets the interest operations for the channel to writability. (A more
complete server would actually attempt to parse the HTTP header request here and
choose the file to send based on that information.) Next, the content buffer is duplicated
and attached to the channel.
Search WWH ::




Custom Search