问题标签 [nio]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
6 回答
8481 浏览

java - 使用 Bytebuffers 和 NIO 时如何避免 OutOfMemoryError?

我正在使用ByteBuffers并将FileChannels二进制数据写入文件。当为大文件或连续为多个文件执行此操作时,我得到一个OutOfMemoryError例外。我在其他地方读到过,Bytebuffers与 NIO 一起使用是坏的,应该避免。你们中是否有人已经遇到过此类问题并找到了一种解决方案,可以有效地将大量二进制数据保存在 java 文件中?

jvm选项-XX:MaxDirectMemorySize是要走的路吗?

0 投票
6 回答
3111 浏览

java - 为什么即使在非阻塞套接字上,SocketChannel 的写入也总是全部完成?

在 Windows 上使用 Sun Java VM 1.5 或 1.6,我连接了一个非阻塞套接字。然后我用一条消息填充一个ByteBuffer要输出的消息,并尝试到write()SocketChannel。

如果要写入的量大于套接字 TCP 输出缓冲区中的空间量,我希望写入仅部分完成(这是我直观地期望的,这也是我对文档的理解),但这不是发生。write() 似乎总是返回报告写入的全部量,即使它是几兆字节(套接字的 SO_SNDBUF 是 8KB,比我的多兆字节输出消息少得多)。

这里的一个问题是我无法测试处理输出被部分写入的情况的代码(将兴趣集注册WRITE到选择器并执行 aselect()等待直到可以写入剩余部分),因为这种情况似乎永远不会发生。我不明白什么?

0 投票
4 回答
5205 浏览

java - Java:是否可以通过 Object(In|Out)putStreams 在阻塞的 SocketChannel 上进行并发读写?

我在阻塞上创建了一个ObjectInputSteamand并试图同时读取和写入。我的代码是这样的:ObjectOutputStreamSocketChannel

问题是行 (B) 处的写入阻塞,直到行 (A) 处的读取完成(阻塞返回的对象SelectableChannel#blockingLock())。但是应用程序逻辑规定,在所有写入完成之前,读取不会完成,因此我们有一个有效的死锁。

SocketChanneljavadocs说支持并发读写。

当我尝试常规的 Socket 解决方案时,我没有遇到这样的问题:

但是,我无法利用FileChannel#transferTo(...)

0 投票
2 回答
6606 浏览

java - Java NIO select() 返回没有选择的键 - 为什么?

在编写一些测试代码时,我发现 Selector.select() 可以在没有包含任何要处理的键的 Selector.selectedKeys() 的情况下返回。当我注册一个接受()ed通道时,这发生在一个紧密的循环中

作为感兴趣的操作。

根据文档, select() 应该在以下情况下返回:

1)有渠道可以采取行动。

2)您明确调用 Selector.wakeup() - 没有选择任何键。

3)您明确 Thread.interrupt() 执行 select() 的线程 - 没有选择任何键。

如果在 select() 之后我没有得到任何键,我必须在情况 (2) 和 (3) 中。但是,我的代码没有调用 wakeup() 或 interrupt() 来启动这些返回。

关于是什么导致这种行为的任何想法?

0 投票
5 回答
6249 浏览

java - java.net 与 java.nio

什么时候从 java.net 切换到 java.nio 更好?.net(不是微软实体)更容易理解和熟悉,而 nio 是可扩展的,并带有一些额外的漂亮功能。

具体来说,我需要针对这种情况做出选择:我们有一个控制中心管理多个远程站点的硬件(每个站点都有一台计算机管理多个硬件单元(收发器、TNC 和旋转器))。我的想法是在每台机器上编写一个服务器应用程序,作为从控制中心到无线电硬件的网关,每个单元都有一个插座。根据我的理解,NIO 是针对一台服务器,多台客户端,但我想的是一台客户端,多台服务器。

我想第三种选择是使用 MINA,但我不确定这是否会在一个简单的问题上投入过多。


每个远程服务器最多有 8 个连接,都来自同一个客户端(用于控制所有硬件和单独的 TX/RX 套接字)。但是,单个客户端将希望同时连接到多个服务器。与其将每个服务器放在不同的端口上,是否可以在客户端使用通道选择器,或者在客户端使用多线程 io 并以不同方式配置服务器是否更好?


实际上,由于远程机器仅用于与其他硬件交互,RMI 或 IDL/CORBA 会是更好的解决方案吗?真的,我只是希望能够从硬件发送命令和接收遥测数据,而不必编写一些应用层协议来做到这一点。

0 投票
3 回答
2641 浏览

java - 当我使用 nio 时,serverSocket.accept() 抛出 IllegalBlockingModeException

当我这样编码时:

ServerSocket.accept()方法抛出java.nio.channels.IllegalBlockingModeException. 为什么我不能打电话accept(),即使我将阻止设置为false

0 投票
4 回答
2329 浏览

java - 如何检测 Selector.wakeup 调用

如果我要写:

它会正确检测到唤醒呼叫吗?

背景资料:

我正在编写一个服务器,它大部分时间只是接收数据包并将它们存储在一个文件中。应用程序很少需要向自己发送一个特殊的数据包。为此,它会(从不同的线程)启动到服务器套接字的连接:

问题是如果主线程已经在 Selector.select() 中,SelectableChannel.register() 可能会阻塞。为了防止这种情况发生,我调用了 Selector.wakeup(),这让主线程过早地从 select() 返回。为了确保其他线程有机会完成注册调用,我必须同步主线程,但我必须在每次从 select() 返回后进行同步。如果我可以检测到它是否因为 wakeup() 调用而从 select() 返回,那么我可以针对这种情况对其进行优化。

所以,理论上最上面的代码片段应该可以工作,但我想知道它是否只会这样做,因为它依赖于一些未指定的行为?

感谢您的任何提示。

0 投票
3 回答
7488 浏览

java - 在码头使用 NIO 与 BIO 的优势?

当为每个查询执行堆和计算密集型进程且执行时间在(100ms-900ms)范围内时,在 nio 与 bio 方面的权衡有什么经验?

0 投票
2 回答
3978 浏览

java - 使用Java的FileLock时,可以让close()自动做一个lock.release()吗?

正如大多数人应该知道的那样,close()也关闭了任何流使用。

这允许以下代码:

这很好,因为我们不需要引用FileInputStream并记得关闭它。

但它也适用于FileLocks 吗?

我已经尝试过这段代码,并且在br.close()调用时锁被正确释放,但是这样做安全吗?Closeable JavaDoc说:“关闭此流并释放与之关联的任何系统资源。” 我可以安全地假设我按照锁close()的规定使用吗?release()

0 投票
5 回答
6854 浏览

java - Java NIO:快速发送大消息会导致数据包被截断和数据丢失

我遇到了这个令人讨厌的问题,即从 Java (NIO) 服务器(运行 Linux)快速连续地向客户端发送多条大消息会导致数据包被截断。消息必须很大并且发送速度非常快,问题才会发生。这基本上是我的代码在做什么(不是实际的代码,而是或多或少发生了什么):

因此,如果数据包足够长并且尽可能快地发送(即在这样的循环中没有延迟),那么在另一端它通常会出现这样的情况:

存在数据丢失,数据包开始一起运行,因此数据包 5 的开头(在此示例中)与数据包 4 的开头到达相同的消息。它不仅仅是截断,而是一起运行消息。

我想这与 TCP 缓冲区或“窗口大小”有关,或者这里的服务器只是提供比操作系统或网络适配器或其他东西更快的数据可以处理它。但是我该如何检查并防止它发生呢?如果我减少每次使用 sc.write() 的消息长度,然后增加重复次数,我仍然会遇到同样的问题。这似乎只是短时间内数据量的问题。我也没有看到 sc.write() 抛出任何异常(我知道在上面的示例中我没有检查,但在我的测试中有)。

如果我能以编程方式检查它是否还没有准备好接收更多数据,我会很高兴,并延迟,等待它准备好。我也不确定是否“sc.socket().setSendBufferSize(1024*1024);” 有任何影响,或者如果我需要在 Linux 方面进行调整。有没有办法真正“冲洗”出 SocketChannel?作为一种蹩脚的解决方法,例如,我可以尝试在任何时候尝试发送超过 10KB 的消息时显式强制发送缓冲的任何内容(这在我的应用程序中并不常见)。但我不知道有什么方法可以强制发送缓冲区(或等到它发送)。谢谢你的帮助!