注:本文参照孙卫琴编写的<<网络编程详解>>
一、先给出一个Demo
1、TestDatagramSocketChannel用来接受数据,等待数据,数据长度为10时写出数据
package com.yezi.datagramtest;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
public class TestDatagramSocketChannel {
private int port[]={8888};
private Selector selector;
public TestDatagramSocketChannel() throws IOException{
selector = Selector.open();
for(int i=0;i<port.length;i++){
DatagramChannel datagramChannel = DatagramChannel.open();
datagramChannel.socket().bind(new InetSocketAddress(port[i]));
datagramChannel.configureBlocking(false);
datagramChannel.register(selector,SelectionKey.OP_READ); //设置成读取操作
}
}
public void testChannel() throws IOException{
byte bytes[] = new byte[1024];
int length=0;
while(true){
int num = selector.select();
if(num>0){
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
if(iterator.hasNext()){
SelectionKey selectionKey = iterator.next();
DatagramChannel datagramChannel=null;
if(selectionKey.isReadable()){
datagramChannel = (DatagramChannel)selectionKey.channel();
ByteBuffer buffer = ByteBuffer.allocate(3);
datagramChannel.receive(buffer);
buffer.flip(); //读取准备
int readLength = buffer.limit();
byte byteread[]=new byte[readLength];
buffer.get(byteread,0,readLength);
System.arraycopy(byteread, 0, bytes,length,readLength);
length+=readLength;
if(length==10){ //读取的数据达到10哥字节,设置成写出
datagramChannel.register(selector,SelectionKey.OP_WRITE);
}
}else if(selectionKey.isWritable()){
datagramChannel = (DatagramChannel)selectionKey.channel();
SocketAddress socketAddress = new InetSocketAddress("127.0.0.1",9998);
datagramChannel.connect(socketAddress);
String string = "123456789";
byte []t= string.getBytes("UTF-8");
ByteBuffer write = ByteBuffer.wrap(t);
while(write.hasRemaining()){
datagramChannel.send(write,socketAddress);
}
datagramChannel.register(selector,SelectionKey.OP_READ);
}
iterator.remove();
}
}
}
}
public static void main(String []args) throws IOException{
new TestDatagramSocketChannel().testChannel();
}
}
2、发送数据,当写入数据为10时进行数据,线程读取数据
package com.yezi.datagramtest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
public class SendTest implements Runnable{
private DatagramSocket datagramSocket;
public SendTest(int port) throws SocketException{
datagramSocket = new DatagramSocket(port);
}
public void test(String str,SocketAddress address) throws Exception{
byte [] bytes = str.getBytes("utf-8");
int sendLength=0;
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,2,address);
while(sendLength<bytes.length){
datagramSocket.send(datagramPacket);
sendLength+=datagramPacket.getLength();
int remain = bytes.length-sendLength;
int length = (remain>2)?2:remain;
datagramPacket.setData(bytes,sendLength,length);
}
}
public static void main(String []args) throws Exception {
SendTest sed = new SendTest(9998);
new Thread(sed).start();
sed.test("1234567890",new InetSocketAddress("127.0.0.1",8888));
}
@Override
public void run() {
while(true){
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,20);
try {
datagramSocket.receive(datagramPacket);
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、在没有绑定固定的远程地址和端口只能使用receive和send方法,绑定了远程地址和端口能使用read和write方法
1、没有绑定固定远程地址和端口,只能使用recive和send
datagramChannel.send(write,socketAddress); 发送方法
datagramChannel.receive(buffer); 读取方法,返回SocketAddress
2、绑定固定的远程地址和远程端口
TestDatagramSocketChannel的构造函数中加入
SocketAddress socketAddress = new InetSocketAddress("127.0.0.1",9998);
datagramChannel.connect(socketAddress);
后可以直接使用int readLength = datagramChannel.read(buffer);代替datagramChannel.receive(buffer);
使用datagramChannel.write(write);代替datagramChannel.send(write,socketAddress);发送数据
三、常见的问题