NIO-DatagramChannel详解

DatagramChannel是NIO中面向Datagram(数据报)的套接字通道.底层为DatagramSocket + selector的高层封装.此接口仍然实现了SeletableChannel,ScatteringByteChannel, GatheringByteChannel .

 

可以通过DatagramChannel.open()方法打开获得通道,但此时尚未链接.DatagramChannel和DatagramSocket对数据发送/接受方式 有些区别.尽管DatagramChannel无需建立链接(远端链接),仍然可以通过isConnect()检测当前channel是否声明了远端链接 地址.

 

DatagramChannel仍然为线程安全的,read和write阻塞方式类似于其他Channel,即当一个线程正在read,其他尝试进行read的线程将被阻塞.源码参见:http://javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/nio/ch/DatagramChannelImpl.java.html

  • public static DatagramChannel open() throw IOException:打开DatagramChannel,底层通过调用系统级默认SelectorProdiver.openDatagramChannel()来创建通道,但是该通道不会链接.
  • public final int validOps():DatagramChannel只支持OP_READ/OP_WRITE两种操作
  • public abstract DatagramSocket socket():获取与其关联的底层DatagramSocket.
  • public abstract boolean isConnected():检测是否已经建立了Socket链接.
  • public abstract DatagramChannel connect(SocketAddress remote):链接remote端.如果当前DatagramSocket资源不存在,则新建(可能是因为此前执行了disconnect方法).向指定的remote地址发送或者接受DatagramPacket.一旦建立链接后(事 实上是本地Socket链接),就无法和任何其他地址进行数据报发送或者接受.(类似于DatagramSocket);底层是类似执行 DatagramSocket.connect(remote)此方法将导致DatagramChannelImpl维持的remoteAddress被复制,此后所有send将会被检测,如果指定的地址remoteAddress地址不同,将会抛出异常.如果想向其他地址send数据,必须disconnect.connect实际上就是创建本地DatagramSocket.
  • public abstract DatagramChannel disconnect() throws IOException:断开通道连接,此方法可以在任何时间执行,但是会阻塞后续的read/write,因为此方法对readLock/writeLock对象锁进行同步.此方法主要目的是将connect()方法中指定的remoteAddress置为null,释放底层的Socket.
  • public abstract SocketAddress receive(ByteBuffer dst) throws IOException:接收数据报.在非阻塞模式下,此方法可能立即返回,当没有数据可用时,为null,此方法适用于作为"Server"端的DatagramChannel.如果缓冲区中的剩余字节空间小于保存数据报所需的空间,则丢弃余下的数据报。此方法同步readLock.并且支持中断响应:begin()/end()方法.操作之前,需要channel.socket().bind();
  • public abstract int send(ByteBuffer src,SocketAddress remote) throws IOException:发送数据.同步writeLock.在非阻塞模式下,此方法可能立即返回0.需要注意,如果在send之前,如果调用了connect(),那么remote地址必须和connect指定的一样,否则将抛出异常.此方法将导致新建DatagramSocket.send操作,在底层最终还是使用了write(ByteBuffer),只不过进行了校验和本地Socket生成策略.在很多情况下,对于被动数据接受方(可以用server端来比喻),通常是receive + send方法.
  • public abstract int read(ByteBuffer dst):仅在此套接字已经连接的情况下,才可用(connect()方法);这个有个特殊的要求,如果实际传输的数据size大于byteBuffer,剩余数据将会被抛弃.次方返回读取的字节个数,如果EOF,则返回-1.在非阻塞模式下,有可能返回0.本方法同步readLock.
  • public abstract int write(ByteBuffer src) throws IOException:向此通道写入数据,本方法将同步writeLock。此方法必须在connect()之后.如果尚未connect(),则抛出异常.此方法在非阻塞模式下,有可能返回0.对于主动数据发送方(client端),通常操作组合为read + write方法.

你可能感兴趣的:(channel)