套接字与套接字通道

2022-08-31 12:54:59

我试图理解SocketChannelsNIO的一般情况。我知道如何使用常规套接字,以及如何制作一个简单的每个客户端线程服务器(使用常规阻塞套接字)。

所以我的问题:

  • 什么是套接字通道?
  • 使用套接字通道而不是套接字时,我得到的额外好处是什么。
  • 通道和缓冲器之间有什么关系?
  • 什么是选择器?
  • 文档中的第一句话是 。那是什么意思?A selectable channel for stream-oriented connecting sockets.

我也阅读了本文档,但不知何故,我没有得到它...


答案 1

A 是阻塞输入/输出设备。它使使用它来阻止读取,并且如果基础缓冲区已满,则可能还会阻止写入。因此,如果您的服务器有一堆打开的线程,则必须创建一堆不同的线程。SocketThreadSocket

A 是一种从套接字读取的非阻塞方式,因此您可以让一个线程同时与一堆打开的连接进行通信。这的工作原理是将一堆 s 添加到 ,然后循环使用选择器的方法,该方法可以在套接字已被接受、接收数据或关闭时通知您。这允许您在一个线程中与多个客户端进行通信,而不会产生多个线程和同步的开销。SocketChannelSocketChannelSelectorselect()

Buffers是NIO的另一个功能,它允许您从读取和写入访问底层数据,以避免将数据复制到新数组的开销。


答案 2

到现在为止,它已经很老了,很少有人记得Java在1.4之前是什么样子的,这是你需要知道的,以便理解的“为什么”。NIONIO

简而言之,在Java 1.3之前,所有I / O都是阻塞类型。更糟糕的是,没有模拟系统调用多路复用I/O。因此,用Java实现的服务器别无选择,只能采用“每个连接一个线程”的服务策略。select()

在Java 1.4中引入的NIO的基本要点是使Java中可用的传统UNIX风格多路复用非阻塞I / O的功能。如果您了解如何对一组文件描述符(通常是套接字)进行编程或检测 I/O 就绪情况,那么您将在中找到所需的服务:您将使用 s 表示非阻塞 I/O 端点,s 用于 fdset 或 pollfd 数组。具有线程池或具有处理多个连接的线程的服务器现在成为可能。这就是“额外”。select()poll()NIOSocketChannelSelector

A 是非阻塞套接字 I/O 所需的字节数组,尤其是在输出/写入端。如果只能立即写入缓冲区的一部分,则使用阻塞 I/O,您的线程将简单地阻塞,直到可以写入整个缓冲区。使用非阻塞 I/O,您的线程将获得写入量的返回值,由您来处理下一轮的剩余部分。A 通过显式实现用于填充和排出的生产者/消费者模式来处理这些机械细节,可以理解您的线程和 JVM 的内核将不同步。BufferBuffer


推荐