ruby - 带有nio4r select循环的Ruby套接字

标签 ruby sockets asynchronous network-programming asyncsocket

假设我有一个选择循环,其中有一些我将要读取的开放连接,并且每个连接上都有状态机,这些状态机用于解析通过线路传输的某些信息并执行正确的操作。因此,假设其中一个连接c已准备就绪,并且select循环将其交给状态机m进行处理。我们想从连接中读取10个字节,我们将使用readpartial。不幸的是,我们只有6个字节,所以m读取6个字节并解除阻塞。下次循环将其交给c时,它还有11个字节。 m仍处于上次选择循环向c传递给我们的状态,并且知道它需要再读取4个字节,因此它使用readpartial(4)读取了这4个字节,并使用现在的那10个字节进行某种副作用操作。它的缓冲区并转移到新状态。 m仍保持连接,因此此时它可以解除阻塞循环或开始执行新状态指示的操作,而这些操作之一很可能涉及readpartial。在这种情况下,正确的做法是继续处理连接,因为readpartial不会阻塞。但是,假设操作顺序是:接收6个字节,读取6个字节并取消阻止,接收4个字节,读取4个字节并执行一些操作。在这种情况下,将没有任何内容可供读取,因此,如果状态机决定在连接上调用readpartial,则它将阻塞选择循环,这是不希望的情况,在这种情况下,正确的做法是针对该状态机器解锁并等待select循环再次出现。

如果我从不希望阻塞选择循环,也不想在连接缓冲区中保留字节,那么解决此问题的正确有效方法是什么?我已经遍历了Ruby的Socket和IO API,我找不到能告诉我是否有东西要读取的方法。 read_nonblock是一种潜在的探索途径,可通过读取单个字节然后将其放回来测试流是否可读,但是在我的测试中,它的行为不符合预期,即即使连接缓冲区有更多缓冲区,char = c.read_nonblock(1); c.ungetc(char); wire_data = c.read_partial(10)也会产生wire_data == char而不是缓冲区中的char

最佳答案

像往常一样写出问题,我一直在帮助我查看解决方案。除了在状态机中调用readpartial之外,我还可以调用read_nonblock。如果没有什么要阅读的,read_nonblock将引发异常,我可以捕获此异常并取消阻塞select循环。

关于ruby - 带有nio4r select循环的Ruby套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15426481/

相关文章:

c++ - 增加特定套接字的 TCP 接收窗口

linux - accept4 和 accept 有什么区别

c++ - Boost asio async_read (async_write) 包装器

javascript - 需要用异步代码解决问题

ruby - 在主线程中创建无限循环,同时在派生线程中创建无限循环

ruby - Ruby 中集合是如何定义的?

ruby - 在 Ruby 中找到第一个可能匹配的哈希键的优雅方式

c# - System.Argument 出现异常 :Specified argument was out of range of valid value

C# 异步串行端口读取

ruby-on-rails - Rails 路由碰撞处理