【SocketChannel详解】

【SocketChannel详解】

SocketChannel

1 定义和特点

selectable channel for stream-oriented connecting sockets.

SocketChannel是一种面向流的连接socket套接字的可选择通道。

具有以下特点:

SocketChannel是用来连接Socket套接字的;

SocketChannel主要用途用来处理网络I/O的通道;

SocketChannel是基于TCP连接传输;

SocketChannel实现了可选择通道,可以被多路复用的。

ServerSocketChannel的属性:

参数名作用描述SO_SNDBUF套接字发送缓冲区大小SO_RCVBUF套接字接收缓冲区大小SO_KEEPALIVE保活连接O_REUSEADDR复用地址SO_LINGER有数据传输时延缓关闭Channel (只有在非阻塞模式下有用)TCP_NODELAY禁用Nagle算法2 使用与相关API

SocketChannel 作为网络 IO 通道,具体负责进行读写操作。NIO 把缓冲区的数据写入通道,或者把通道里的数据读到缓冲区。

1.创建SocketChannel

//方式1

SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 6666));

//方式2

SocketChannel socketChannel = SocketChannel.open();

socketChannel.connect(new InetSocketAddress("127.0.0.1", 6666));

方式1是有参构造,构造的同时进行了tcp连接

方式2是无参构造,先创建SocketChannel对象,再tcp连接到服务器。

2.连接校验

// 测试SocketChannel是否为open状态

socketChannel.isOpen();

//测试SocketChannel是否已经被连接

socketChannel.isConnected();

//测试SocketChannel是否正在进行连接

socketChannel.isConnectionPending();

//校验正在进行套接字连接的SocketChannel是否已经完成连接

socketChannel.finishConnect();

3.读写模式

SocketChannel支持阻塞和非阻塞两种模式:

socketChannel.configureBlocking(false);

主要是通过以上方法设置SocketChannel的读写模式。false表示非阻塞,true表示阻塞。

4.设置和获取属性

socketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE)

.setOption(StandardSocketOptions.TCP_NODELAY, Boolean.TRUE);

通过setOptions方法可以设置socket套接字的相关参数。

socketChannel.getOption(StandardSocketOptions.SO_KEEPALIVE)

socketChannel.getOption(StandardSocketOptions.SO_RCVBUF)

可以通过getOption获取相关参数的值。

使用注意点:

对于已经存在的socket不能创建SocketChannel

SocketChannel支持两种I/O模式:阻塞式和非阻塞式

SocketChannel支持异步关闭。如果SocketChannel在一个线程上read阻塞,另一个线程对该SocketChannel调用shutdownInput,则读阻塞的线程将返回-1表示没有读取任何数据;如果SocketChannel在一个线程上write阻塞,另一个线程对该SocketChannel调用shutdownWrite,则写阻塞的线程将抛出AsynchronousCloseException。

3 SocketChannel和Socket

Socket(套接字)是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,Socket对象中封装了连接节点的IP地址、端口、协议等信息,是TCP连接的主要API。

socketChannel 套接字通道类(如DatagramChannel、SocketChannel 和ServerSocketChannel)在被实例化时都会创建一个对等 socket 对象(来自 java.net 的类Socket、ServerSocket 和 DatagramSocket),它们已经被更新以识别通道。Socket和Channel之间可以相互得到。

Socket socket = socketChannel.socket();

SocketChannel socketChannel = socket.getChannel();

相关推荐