1、API
⑴ 数据报通道
DatagramChannel.open();
获取数据包通道实例
⑵ 切换为非阻塞模式
configureBlocking(false);
⑶ 设置key上的通道的监听模式
register(Selector sel, int ops);
第一个参数为选择器;第二个参数为SelectionKey的监听模式
SelectionKey.OP_READ = 1 读
SelectionKey.OP_WRITE = 4 写
SelectionKey.OP_CONNECT = 8 连接
SelectionKey.OP_ACCEPT =16 接收
⑷ 发送数据报
send(ByteBuffer src, SocketAddress target);
第一个为字节缓冲区;第二个参数为要发送的地址,使用InetSocketAddress(String hostname, int port)即可
⑸ 接收数据报
receive(ByteBuffer dst);
将接收到的数据报,复制到指定的字节缓冲区中
⑹ 绑定端口
bind(SocketAddress local);
使用InetSocketAddress(int port)即可
2、接收端
DatagramChannel receiver = null;
try {
receiver = DatagramChannel.open();
receiver.bind(new InetSocketAddress(???));
receiver.configureBlocking(false); // 切换为非阻塞式
Selector selector = Selector.open();
receiver.register(selector, SelectionKey.OP_READ); // 监听键上的通道的读取模式
while (0 < selector.select()) {
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
SelectionKey selectionKey;
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (iterator.hasNext()) {
selectionKey = iterator.next();
if (selectionKey.isReadable()) {
receiver.receive(byteBuffer);
byteBuffer.flip();
System.out.println(new String(byteBuffer.array(), 0, byteBuffer.limit()));
byteBuffer.clear();
}
iterator.remove(); // 移除选择器的监听,否则一旦接收到消息,会停止程序的
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != receiver) {
try {
receiver.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、发送端
DatagramChannel sender = null;
Scanner scanner = null;
try {
sender = DatagramChannel.open();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
sender.configureBlocking(false); // 切换为非阻塞模式
scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String next = scanner.nextLine();
byteBuffer.put(next.getBytes());
byteBuffer.flip();
sender.send(byteBuffer, new InetSocketAddress("???.???.???.???", ???));
byteBuffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != scanner) {
scanner.close();
}
if (null != sender) {
try {
sender.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}