Java Reference
In-Depth Information
allow each channel to run at its own speed. For example, recall the single-file HTTP
server in
Example 9-10
. Reimplemented with channels and buffers as shown in
Example 11-6
,
NonblockingSingleFileHTTPServer
, the single file to serve is stored in
one constant, read-only buffer. Every time a client connects, the program makes a du‐
plicate of this buffer just for that channel, which is stored as the channel's attachment.
Without duplicates, one client has to wait until the other finishes so the original buffer
can be rewound. Duplicates enable simultaneous buffer reuse.
Example 11-6. A nonblocking HTTP server that serves one file
import
java.io.*
;
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.nio.charset.*
;
import
java.nio.file.*
;
import
java.util.*
;
import
java.net.*
;
public
class
NonblockingSingleFileHTTPServer
{
private
ByteBuffer
contentBuffer
;
private
int
port
=
80
;
public
NonblockingSingleFileHTTPServer
(
ByteBuffer
data
,
String
encoding
,
String
MIMEType
,
int
port
)
{
this
.
port
=
port
;
String
header
=
"HTTP/1.0 200 OK\r\n"
+
"Server: NonblockingSingleFileHTTPServer\r\n"
+
"Content-length: "
+
data
.
limit
()
+
"\r\n"
+
"Content-type: "
+
MIMEType
+
"\r\n\r\n"
;
byte
[]
headerData
=
header
.
getBytes
(
Charset
.
forName
(
"US-ASCII"
));
ByteBuffer
buffer
=
ByteBuffer
.
allocate
(
data
.
limit
()
+
headerData
.
length
);
buffer
.
put
(
headerData
);
buffer
.
put
(
data
);
buffer
.
flip
();
this
.
contentBuffer
=
buffer
;
}
public
void
run
()
throws
IOException
{
ServerSocketChannel
serverChannel
=
ServerSocketChannel
.
open
();
ServerSocket
serverSocket
=
serverChannel
.
socket
();
Selector
selector
=
Selector
.
open
();
InetSocketAddress
localPort
=
new
InetSocketAddress
(
port
);
serverSocket
.
bind
(
localPort
);
serverChannel
.
configureBlocking
(
false
);
serverChannel
.
register
(
selector
,
SelectionKey
.
OP_ACCEPT
);
while
(
true
)
{