Java NIO:何时在OP之间正确切换
作为一些背景:
我有一个与SocketChannel,SelectionKey等的服务器连接。 在客户端,如果我想将某些内容发送到服务器,我只需将我的数据写入ByteBuffer并通过套接字通道发送。 如果全部写完了,我就完成了,可以返回到OP_READ。 如果不是全部写入,我将剩余的字节存储在某个地方的“发送”缓冲区中,并在该按键上标记OP_WRITE(是否将OP_READ替换为唯一写入?)。
因此,下次我调用selectNow()时,我假设它会识别OP_WRITE并尝试刷新更多数据(我将尝试通过输入另一个写入循环来写入数据,并在需要时重复以前的操作)。
这导致我有两个问题:
如果写作通道已满并且我无法写入,那么我是否可以继续循环,直到我可以开始写东西? 如果连接突然被阻塞,我不确定是否应该只写我能做的事,翻回OP_READ,尝试读取,然后翻回OP_WRITE。 从我读过的内容来看,这似乎不是正确的做事方式(并且可能会导致大量开销不停地来回切换?)。
阅读听起来很容易,因为你只是循环浏览直到数据被使用,但是在写入时......服务器可能只是书写而不是阅读。 这会给你带来一个完整的发送缓冲区,并且在没有读取的情况下在OP_WRITE上永远循环播放会很糟糕。 你如何避免这种情况? 如果发送缓冲区未清除,您是否设置了一个定时器,在该定时器中,您只是停止尝试写入并重新开始读取? 如果是这样,你是否删除OP_WRITE并在以后记住它?
侧面问题:你甚至需要OP_READ从网络上读取吗? 我不确定它是否像OP_WRITE那样只在特定情况下标记它(只是在我'做错了,因为我在99.9%的时间在OP_READ上)。
目前,我只是将密钥设置为OP_READ,然后将其保留在该模式下,等待数据,并且当且仅当写入无法发送所有数据(write()值为0)时才转至OP_WRITE。
我是否应该将其保留在OP_WRITE中,直到所有数据都被刷新为止? 或者我应该更改为OP_READ并尝试在两者之间进行读取?
对此有不同的看法。 我的意思是,同伴应该在发送新请求之前阅读你发送的回复的每一部分,如果他不是,他只是行为不端,而你不应该通过阅读提前鼓励。 否则,你最终会耗尽内存,而且你不应该让客户那么做。 当然,假设你是请求响应协议中的服务器。 其他情况有他们自己的要求。
如果写作通道已满并且我无法写入,那么我是否可以继续循环,直到我可以开始写东西?
不,您等待OP_WRITE启动。
如果连接突然被阻塞,我不确定是否应该只写我能做的事,翻回OP_READ,尝试读取,然后翻回OP_WRITE。 从我读过的内容来看,这似乎不是正确的做事方式(并且可能会导致大量开销不停地来回切换?)。
开销并不重要,但在上述情况下这是错误的。
当缓冲区可能变满时,处理读取和写入批量数据的最佳方式是什么?
一般来说,在OP_READ触发时读取; 随时写字; 并使用OP_WRITE告诉你何时出站摊位已经释放。
你甚至需要OP_READ从网络上读取吗?
是的,否则你只是抽出CPU。
每当你需要编写只需设置感兴趣的操作(OP_READ || OP_WRITE)。 完成写作时,只需将感兴趣的操作设置为OP_READ。
这就是你所要做的。
链接地址: http://www.djcxy.com/p/34133.html上一篇: Java NIO: When to properly switch between OP
下一篇: is there any way to send data as response from nio server to io client?