我正在构建一个通过TCP(使用TCPServer)接受连接的服务器。我主要只是读取数据(socket.gets.chomp
)和写入数据(socket.print
)。
如果客户端在此期间关闭了连接,socket.gets
将返回nil
,因此.chomp
将引发NoMethodError
。这很难处理,因为它是一个不特定的异常——我想把连接丢失引起的异常与NoMethodError
的其他原因(比如我输入了一个方法)区分开来。
理想情况下,每当尝试与关闭的套接字交互时,我都会收到更具体的内容,例如SocketError
,而不仅仅是返回nil
。我怎么才能做到呢?
我已经考虑过这些选项:
- 为
TCPSocket
或IO
编写一个包装器,在每次调用之前检查套接字可用性(考虑到IO
中有多少方法,要做很多工作) - 检查
nil
的每个返回值(随着应用程序的增长,甚至更多的努力和代码冗余,当套接字已经关闭时,我仍然会.print
到套接字) - 为
chomp
打猴补丁NilClass
(同样只处理这个特定的用例,对于干净的代码应该避免打猴补丁)
位于文件末尾本身并不是错误,通常也不理解为"中断"。如标题所示。
例如,HTTP允许通过单个连接发送多个请求。在完全读取请求后,您可以再次读取,如果连接关闭,您将获得nil
,这告诉您没有更多的请求。大多数/所有HTTP软件都不认为这种情况是错误条件。
大多数Ruby软件处理read
返回的nil
作为网络会话结束(成功)的指示。我建议你这样做。
如果您希望将EOF视为错误,您可以为IO创建一个包装器类来"升级"。nil
从read
返回为某种异常,但我建议重新考虑这是否真的是您需要的。
参见https://ruby-doc.org/core-3.0.0/IO.html#method-i-read。