【问题标题】:how to tell the server EOF for ruby socket如何告诉服务器 EOF 用于 ruby​​ 套接字
【发布时间】:2016-02-29 05:36:52
【问题描述】:

服务器.rb

require 'socket'
Socket.tcp_server_loop(6666) do |connection|
  while data = connection.read(1024 * 16) do
    if data == 'hello'
      connection.write('hi hi hi hi hi')
    end
  end
  connection.close
end

client.rb 需要“插座” 需要'io/控制台'

client = TCPSocket.new('localhost', 6666)
client.write('hello')
client.flush
# client.close_write
# client.close_write
# client.fdatasync
# client.fsync

data = client.read
puts data

# client.open
# client.write('hello')
# puts client.read

我想重复使用 socke,所以我不想关闭它。

但如果我不发送 client.close_write ,它就不起作用,无法读取服务器数据。 如果 client.close_write 套接字关闭,则不会再向服务器写入数据。

我想知道如何告诉 EOF 并且不要关闭套接字? `fdatasync' 中的 client.fdatasync =>:不支持操作 (Errno::ENOTSUP)

client.fsync => 在 `fsync' 中:不支持操作 (Errno::ENOTSUP)

我认为 fdatasync 和 fsync 可能是告诉 EOF 的方法,但它们不起作用。

c 语言有一种方法可以做到这一点: ssize_t 发送(int sockfd,const void *buff,size_t nbytes,int 标志) nbytes 告诉服务器数据大小。 ruby 中没有这样的方法。

【问题讨论】:

    标签: ruby-on-rails ruby sockets


    【解决方案1】:

    c 语言有一个方法可以做到这一点: ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags) nbytes 告诉服务器数据大小。

    C 没有这样做的方法。 nbytes in send 告诉 send 要发送多少 buff,并且不会将 EOF 传达给另一方。 Ruby 是等价的:除了关闭时,套接字中没有 EOF。 EOF 是一个条件(一个流已经到达终点的标志);它通常不作为可以自身传播的东西而存在。

    或者,您可以发送内容的大小:这就是 HTTP 中 Content-Length 标头的用途。 Web 服务器在正文开始后收到Content-Length 字节时认为请求已完成。如果服务器在响应中也发送了Content-Length,那么客户端就知道服务器何时完成而服务器没有断开连接,并且可以重用连接。另一种表示结束的方式是使用一个明确表示结束的标记。您可以使用 EOT 字符 (0x04),只要您不传输任何可能自然包含它的内容(通常,文本 OK,二进制数据不行)。如果您正在传输可能包含 EOT 的数据,您可以对它们进行编码,使其变得不可能(例如使用 Base64)。

    【讨论】:

    • 我没有找到告诉 tcp 服务器我的内容大小(Content-Length)的方法,所以发送 EOT 是唯一的方法。
    • 没有办法——你需要开发一个协议(例如“我会先给你长度,然后是那么多字节”)。尝试阅读有关 HTTP 的内容,它很有启发性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2019-12-10
    • 2017-06-18
    • 1970-01-01
    • 2012-03-28
    • 2021-08-30
    相关资源
    最近更新 更多