介绍
① ServerSocketChannel:对应的是服务端通道的实现。通过监听TCP/IP连接,对每一个新的连接创建新的SocketChannel。SocketChannel:通过TCP/IP协议读取网络数据,客户端连接通信。
② ServerSocketChannel使用调用 socket方法所获得的关联 对象来完成对套接字选项的绑定和操作。像open方法只是创建服务器套接字通道,但是却还未绑定IP和端口号。
③ SocketChannel本身是套接字通道,但是却不是真正的套接字。所以我们需要使用socket方法获取Sokcet套接字进行绑定IP和端口。
④ ServerSocketChannel、SocketChannel都支持非阻塞的连接。
注意:我们不能为已经创建的Socket的套接字创建通道。
例子
服务端:
public class NIOSocketServerTest {
public static void main(String[] args) throws IOException {
// 打开服务器套接字通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 获取与此通道关联的服务器套接字
ServerSocket socket = serverSocketChannel.socket();
// 将 ServerSocket 绑定到特定地址(IP 地址和端口号)
socket.bind(new InetSocketAddress("127.0.0.1", 9999));
// 设置通道为非阻塞模式
serverSocketChannel.configureBlocking(false);
while (true) {
SocketChannel socketChannel = serverSocketChannel.accept();
if (socketChannel != null) {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
// 将字节序列从此通道中读入给定的缓冲区
socketChannel.read(byteBuffer);
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
System.out.print((char) byteBuffer.get());
}
socketChannel.close();
}
}
}
}
客户端:
public class NIOSocketClientTest {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
// 完成套接字通道的连接过程
if (socketChannel.finishConnect()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("sunpy".getBytes());
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
socketChannel.close();
}
}
解释:
connect方法作用是连接指定通道的套接字;finishConnect方法作用是完成套接字通道的连接过程。
结果:
2.jpg
问题:
看上面的例子可以发现服务器死循环的方式来一直等待客户端的连接和读写是不合理的。而这时就需要Selector选择器来解决这个问题。