基于JavaAPI实现消息方式的系统通信:UDP/IP+NIO,与UDP/IP+BIO类似,只不过NIO是非阻塞。使用上与TCP/IP+NIO类似,也是用到了Selector。
* DatagramChannel负责监听和读写,ByteBuffer用于数据流传输
代码实现:
public class UdpIpNioJavaMethod {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
new UdpIpNioJavaMethod().send();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
new UdpIpNioJavaMethod().receive();
}
}).start();
}
public void send(){
DatagramChannel sendChannel=null;
Selector selector=null;
try {
sendChannel=DatagramChannel.open();
sendChannel.configureBlocking(false);//设置非阻塞
SocketAddress target=new InetSocketAddress("127.0.0.1",1234);
sendChannel.connect(target);
selector=Selector.open();
sendChannel.register(selector, SelectionKey.OP_WRITE);
while(true){
if(selector.select()==0){
continue;
}
Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();
while(keyIter.hasNext()){
SelectionKey key=keyIter.next();
keyIter.remove();
if(key.isWritable()){
ByteBuffer buffer=ByteBuffer.wrap(new String("Hello,I am Server!")
.getBytes());
DatagramChannel channel= (DatagramChannel) key.channel();
long successedNum=channel.write(buffer);//向信道中写数据
System.out.println("endoff send msg to client
,send successed char :"+successedNum);
}
}
return;
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
sendChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void receive(){
DatagramChannel receiveChannel=null;
Selector selector=null;
try {
receiveChannel=DatagramChannel.open();
receiveChannel.configureBlocking(false);//设置非阻塞
DatagramSocket socket=receiveChannel.socket();
socket.bind(new InetSocketAddress(1234));
selector=Selector.open();
receiveChannel.register(selector, SelectionKey.OP_READ);
while(true){
if(selector.select()==0){
continue;
}
Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();
while(keyIter.hasNext()){
SelectionKey key=keyIter.next();
keyIter.remove();
if(key.isReadable()){
DatagramChannel channel= (DatagramChannel) key.channel();
ByteBuffer buffer=ByteBuffer.allocate(2000);
channel.receive(buffer);//注意UDP/IP+NIO这个是receive
String msg=new String(buffer.array());
System.out.println("Server receive msg:"+msg);
}
}
return;
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
receiveChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1、发送端DatagramChannel应该注册:sendChannel.register(selector,SelectionKey.OP_WRITE);
2、接收端DatagramChannel应该注册:receiveChannel.register(selector,SelectionKey.OP_READ);
3、DatagramChannel使用receive方法,若使用了read方法会报错: java.nio.channels.NotYetConnectedException