NIO 学习(五) SocketChannel

来源:互联网 发布:java管理系统案例 编辑:程序博客网 时间:2024/06/09 07:31

SocketChannel是NIO中连接到TCP网络套接字的信道,创建的两种情况

1. 在客户端,打开一个socketchannel并连接到某台服务器上

2. 在服务器,一个新的连接到达SocketServerChannel,会创建一个SocketChannel

打开一个SocketChannel

SocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("127.0.0.1", 23000));
关闭SocketChannel   socketChannel.close()

从SocketChannel读取数据

ByteBuffer byteBuffer = ByteBuffer.allocate(38);socketChannel.read(byteBuffer);
socketchannel的read方法,将通道里面的数据put到buffer中,read方法返回的int值,表示放到buffer中的字节数,如果返回-1,表示到达流末尾

信道的read方法隐式调用了缓冲区的put方法,调用read方法钱,需要调用缓冲区的clear方法

写入SocketChannel

String str = "data for testing";byteBuffer.clear();byteBuffer.put(str.getBytes());byteBuffer.flip();while(byteBuffer.hasRemaining()){socketChannel.write(byteBuffer);}
write的方法的调用是在一个while循环中,write方法无法保证写入多少字节到信道中,hasRemaing检查缓冲区区是否还有数据,while循环直到缓冲区的数据全部写入到信道中

信道的write方法隐式调用了缓冲区的get方法,在调用信道的write方法前,需要先调用缓冲区的flip方法

非阻塞模式non-blocking mode

socketChannel.configureBlocking(false);
调用configureBlocking ,false设置为non-blocking mode(非阻塞模式),true 设置为blocking mode 阻塞模式

非阻塞模式下能异步调用connect,write,read方法


non-blocking-mode connect

非阻塞模式下调用connect方法,可能在连接没有建立的时候,就返回了,可以使用finishConnect方法检查

SocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("127.0.0.1", 23000));socketChannel.configureBlocking(false);while(!socketChannel.finishConnect()){//没有连接上  do something else}

non-blocking-mode write

非阻塞模式下调用 write方法,可能在没有写出任何字节就返回了,需要在while循环中检查

String str = "data for testing";byteBuffer.clear();byteBuffer.put(str.getBytes());byteBuffer.flip();while(byteBuffer.hasRemaining()){socketChannel.write(byteBuffer);}
non-blocking-mode read

非阻塞模式下调用read方法,可能没有读取到任何字节,需要关注read的返回值(返回-1,到达流末尾)


non-blocking-mode 非阻塞模式存在的目的和选择器搭配,多个socketChannel注册到了selector上,selector选择器就能选择其中一个channel进行write,read操作,其他的channel也不会因为阻塞浪费资源

参照:http://ifeve.com/socket-channel/  加上自己的理解

原创粉丝点击