Java Reference
In-Depth Information
public
int
write
(
ByteBuffer
src
)
throws
IOException
public
long
write
(
ByteBuffer
[]
dsts
)
throws
IOException
public
long
write
(
ByteBuffer
[]
dsts
,
int
offset
,
int
length
)
throws
IOException
These methods can only be used on connected channels; otherwise, they don't know
where to send the packet. Each of these methods sends a single datagram packet over
the connection. None of these methods are guaranteed to write the complete contents
of the buffer(s). Fortunately, the cursor-based nature of buffers enables you to easily call
this method again and again until the buffer is fully drained and the data has been
completely sent, possibly using multiple datagram packets. For example:
while
(
buffer
.
hasRemaining
()
&&
channel
.
write
(
buffer
)
!=
-
1
)
;
You can use the read and write methods to implement a simple UDP echo client. On
the client side, it's easy to connect before sending. Because packets may be lost in transit
(always remember UDP is unreliable), you don't want to tie up the sending while waiting
to receive a packet. Thus, you can take advantage of selectors and nonblocking I/O.
These work for UDP pretty much exactly like they worked for TCP in
Chapter 11
. This
time, though, rather than sending text data, let's send one hundred
int
s from 0 to 99.
You'll print out the values returned so it will be easy to figure out if any packets are being
lost.
Example 12-17
demonstrates.
Example 12-17. A UDP echo client based on channels
import
java.io.*
;
import
java.net.*
;
import
java.nio.*
;
import
java.nio.channels.*
;
import
java.util.*
;
public
class
UDPEchoClientWithChannels
{
public
final
static
int
PORT
=
7
;
private
final
static
int
LIMIT
=
100
;
public
static
void
main
(
String
[]
args
)
{
SocketAddress
remote
;
try
{
remote
=
new
InetSocketAddress
(
args
[
0
],
PORT
);
}
catch
(
RuntimeException
ex
)
{
System
.
err
.
println
(
"Usage: java UDPEchoClientWithChannels host"
);
return
;
}
try
(
DatagramChannel
channel
=
DatagramChannel
.
open
())
{
channel
.
configureBlocking
(
false
);
channel
.
connect
(
remote
);
Selector
selector
=
Selector
.
open
();