当前位置: 首页 > 知识库问答 >
问题:

插座与插座通道

戚永福
2023-03-14

我试图了解Socketchannes和NIO的总体情况。我知道如何使用常规套接字,以及如何为每个客户机服务器创建一个简单的线程(使用常规阻塞套接字)。

所以我的问题是:

  • 什么是袜子通道
  • 当我使用SocketChannel而不是Socket时,额外得到了什么
  • 通道和缓冲区之间的关系是什么
  • 什么是选择器
  • 文档中的第一句话是面向流的连接插座的可选通道 。这是什么意思

我也读了这个留档,但不知何故,我没有得到它...


共有3个答案

凌琦
2023-03-14

即使您使用的是SocketChannels,也有必要使用线程池来处理通道

想想这个场景,你只使用一个线程,它负责轮询选择()和处理从选择器中选择的SocketChannel,如果一个通道需要1秒钟的时间来处理,并且有10个通道在排队,这意味着你必须等待10秒钟才能进行下一次轮询,这是不可容忍的。所以应该有一个线程池来处理通道。

主要的区别是在NIO模式中,任务更小,更像是每个任务的线程,任务可以是读、写、biz进程等。要了解更多详细信息,您可以查看Netty实现的NioServerSocketChannelFactory,它使用一个Boss线程接受连接,并将任务分派到一个Worker线程池进行处理

如果你真的喜欢一个线程,底线是至少你应该有池I/O线程,因为I/O操作通常比指令处理周期慢很多,你不会希望宝贵的一个线程被I/O阻塞,这正是NodeJ所做的,使用一个线程接受连接,所有I/O都是异步的,由后端I/O线程池并行处理

老式的每个客户端线程已经死了吗?我不这么认为,NIO编程很复杂,多线程并不是天生的邪恶,请记住,现代操作系统和中央处理器在多任务处理方面越来越好,所以多线程的开销随着时间的推移会越来越小。

宇文智敏
2023-03-14

到目前为止,NIO太老了,以至于很少有人记得Java在1.4之前是什么样子,这是您需要知道的,以便理解NIO的“为什么”。

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

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

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

白子明
2023-03-14

插座是一种阻塞输入/输出设备。如果底层缓冲区已满,它会使使用它阻止读取的线程,并可能阻止写入。因此,如果你的服务器有一堆打开的Sockets,你必须创建一堆不同的线程。

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

缓冲区是NIO的另一个特性,它允许您从读取和写入中访问底层数据,以避免将数据复制到新数组中的开销。

 类似资料:
  • 在这种情况下,优化sockets java中的perfomance,使用sockets是BufferedWriter还是PrintWriter更好?

  • 我目前正在编写一个简单的TCP聊天客户端服务器应用程序,它与套接字一起工作。客户端连接到服务器,一旦被接受,就会创建一个新的工作线程来侦听客户端输入。连接到服务器(端口8818处的localhost)工作正常,但只要工作线程在登录java.net之后开始监听更多客户端输入。SocketException:引发连接重置(请参阅下面的堆栈跟踪)。我知道,此异常的一个可能来源可能是服务器或客户端未正确或

  • 我是enterprise social network product的开发人员,我正在开发一个非常类似于Facebook通知的功能。我们想为我们的客户提供一个实时的通知机制。 我正在Node.js中构建一个通知服务,我的系统可以与它交互并通知它。最大的问题是:

  • 问题是我的heroku应用程序无法连接到插座。 超时后,heroku应用程序在第二行失败。当我在我的笔记本电脑或朋友的笔记本电脑上运行相同的东西时(而在这两种情况下,充当服务器的python脚本都在我的笔记本电脑上运行),它可以工作。有人知道为什么heroku会有问题吗?谢了!

  • 问题内容: Java 类有两种方法,分别检查套接字是关闭还是连接。我想知道仅开放的TCP套接字与开放和连接的TCP套接字有什么区别,这与UDP有何不同。 问题答案: 为了把事情简单地说,这是 开放的 是要么等待连接或已与另一个成功连接的插座。当一个套接字被 关闭 ,这意味着这个套接字没有连接不再可用,而且它的资源已被释放。一个已连接的好,这意味着该套接字已连接到另一个。 这样可以 同时打开并连接。