Java|Java:了解Java中的异步套接字通道

Java|Java:了解Java中的异步套接字通道

文章图片


socket编程的阻塞模式效率低下 , 但却是Java中典型socket编程的精髓 。 但是 , 还有其他技术 。 例如采用异步套接字通道 , 通过套接字建立通信 , 这可以大大降低效率 。

插座
在典型的套接字编程情况下 , 即使用 TCP 和 UDP 套接字的情况下 , I/O 操作以阻塞和同步模式工作 。 这意味着当客户端套接字的线程调用读取操作时 , 它会阻塞服务器 , 直到数据可用 。 如果底层缓冲区已满 , 这也可能会阻止写入 。 这使得其他客户端套接字线程停止 , 直到通道被释放 。 这种类型的通道阻塞显然是低效的 。 为了克服这种情况 。 相反 , 可以做的是等到线程完成其工作 。 客户端套接字可以在服务器提供数据后立即通知;同时 , 其他线程可以做其他事情 , 直到来自服务器的数据到达 。 如果服务器有多个打开的套接字 , 另一种方法是创建单独的线程进行通信 。 无论哪种情况 , 这都是一种解决方法 , 而不是适当的解决方案 。 然而 , 正如我们将看到的 , Java 通过 SocketChannel 为这个问题提供了一个解决方案 。

套接字通道
【Java|Java:了解Java中的异步套接字通道】另一方面 , 套接字通道是与服务器套接字建立通信的非阻塞方式 。 在这里 , 我们可以让一个线程同时与多个打开的连接进行通信 。 这是通过向 Selector 添加一堆 SocketChannel 来实现的 。 选择器对象位于客户端和服务器之间 。 客户端套接字线程通过循环选择器的 select 方法来获取套接字通道 。 它可以通知套接字通道的状态是否已被接受、接收数据或关闭 。 这种技术可以在单个线程中与多个客户端进行通信 , 而无需维护多个线程和同步的开销 。 你可以在图 1 中看到这一点 。

异步套接字通道
支持异步套接字通道的类实际上是 Java NIO API 库的一部分 。 思路是通过sockets实现非阻塞异步IO通信 。 异步 IO 利用回调代码在 IO 完成时执行 , 非阻塞的思想是指立即返回的 IO 操作 , 可以有数据 , 也可以没有数据 , 或者错误代码 。 这意味着 , 在从非阻塞通道读取时 , 返回值或阻塞通道没有延迟 , 直到返回有形的东西 。 有两个与异步套接字操作相关的关键类 。 它们是 AsynchronousServerSocketChannel 和 AsynchronousSocketChannel;两者都可以在名为 java.nio.channels 的包中找到 。
AsynchronousServerSocketChannel 类的对象指定侦听传入客户端连接请求的套接字服务器 。 只有在接受请求后才能开始交互 。 名为 AsynchronousSocketChannel 的类负责客户端和服务器两端的所有建立交互 。
普通的 , 也就是同步套接字连接和异步套接字连接之间的主要区别在于 , 在后一种情况下 , 请求者会在每个操作完成后立即得到通知 。 同步套接字连接不是这种情况 , 因为在这种情况下 , 它会阻塞通道 , 直到请求完成 。
由于套接字通道的异步特性 , 有一个处理程序负责处理套接字操作的成功或失败状态 。