Java Reference
In-Depth Information
out
.
write
(
'\n'
);
// linefeed
start
=
((
start
+
1
)
-
firstPrintableCharacter
)
%
numberOfPrintableCharacters
+
firstPrintableCharacter
;
}
}
An
OutputStream
is passed to the
generateCharacters()
method in the
out
argument.
Bytes are written onto
out
one at a time. These bytes are given as integers in a rotating
sequence from 33 to 126. Most of the arithmetic here is to make the loop rotate in that
range. After each 72-character chunk is written, a carriage return and a linefeed are
written onto the output stream. The next start character is calculated and the loop
repeats. The entire method is declared to throw
IOException
. That's important because
the character-generator server will terminate only when the client closes the connection.
The Java code will see this as an
IOException
.
Writing a single byte at a time is often inefficient. For example, every TCP segment
contains at least 40 bytes of overhead for routing and error correction. If each byte is
sent by itself, you may be stuffing the network with 41 times more data than you think
you are! Add overhead of the host-to-network layer protocol, and this can be even worse.
Consequently, most TCP/IP implementations buffer data to some extent. That is, they
accumulate bytes in memory and send them to their eventual destination only when a
certain number have accumulated or a certain amount of time has passed. However, if
you have more than one byte ready to go, it's not a bad idea to send them all at once.
Using
write(byte[] data)
or
write(byte[] data, int offset, int length)
is
normally much faster than writing all the components of the
data
array one at a time.
For instance, here's an implementation of the
generateCharacters()
method that
sends a line at a time by packing a complete line into a byte array:
public
static
void
generateCharacters
(
OutputStream
out
)
throws
IOException
{
int
firstPrintableCharacter
=
33
;
int
numberOfPrintableCharacters
=
94
;
int
numberOfCharactersPerLine
=
72
;
int
start
=
firstPrintableCharacter
;
byte
[]
line
=
new
byte
[
numberOfCharactersPerLine
+
2
];
// the +2 is for the carriage return and linefeed
while
(
true
)
{
/* infinite loop */
for
(
int
i
=
start
;
i
<
start
+
numberOfCharactersPerLine
;
i
++)
{
line
[
i
-
start
]
=
(
byte
)
((
i
-
firstPrintableCharacter
)
%
numberOfPrintableCharacters
+
firstPrintableCharacter
);
}
line
[
72
]
=
(
byte
)
'\r'
;
// carriage return
line
[
73
]
=
(
byte
)
'\n'
;
// line feed
out
.
write
(
line
);
start
=
((
start
+
1
)
-
firstPrintableCharacter
)
%
numberOfPrintableCharacters
+
firstPrintableCharacter
;