Ruby TCPSocket写不起作用,但是put呢?

我正在使用GServer和TCPSocket处理Ruby TCP客户端/服务器应用程序。 我遇到了一个我不明白的问题。 我的TCPSocket客户端成功连接到我的GServer,但我只能使用puts发送数据。 调用TCPSocket.send或TCPSocket.write什么都不做。 我缺少一些魔法吗?

tcp_client = TCPSocket.new( ipaddr, port ) tcp_client.puts( 'Z' ) # -> GServer receives "Z\n" 

但如果我使用写或发送…

 tcp_client = TCPSocket.new( ipaddr, port ) tcp_client.write( 'Z' ) # -> nothing is received tcp_client.send( 'Z' ) # -> nothing is received 

谢谢您的帮助

附加信息:

  1. Linux和Windows上的行为是相同的。
  2. 写入后刷新套接字不会改变行为。

您确定问题不在服务器端吗? 您是否正在使用某种方法来读取需要字符串或以“\ n”结尾的内容?

通过在之前的post中处理缓冲来解决数据是否被发送的问题,考虑使用wireshark之​​类的东西捕获线路上的数据。 如果您正在发送的数据在线路上,则服务器未接收到该数据。

否则,如果数据没有进入线路,TCP可能会保留数据以避免发送只有几个字节的单个段( 参见Nagle的算法 )。 根据您的操作系统或TCP供应商,您可能有不同的行为,但大多数TCP堆栈支持TCP_NODELAY选项,这可能有助于更及时地获取数据。

 tcp_client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) 

这可以帮助调试,但如果吞吐量优先于响应性,则通常不应该留在生产代码中。

尝试明确刷新:

 tcp_client = TCPSocket.new( ipaddr, port ) tcp_client.write( 'Z' ) tcp_client.send( 'Z' ) tcp_client.flush 

这样,输出最多只会被缓冲,直到您决定发送它为止。

嗨那里的原因应该与事实相关,添加自动LF和CRL到您的字符串。 如果你想使用发送或写入,你需要自己添加它们,例如:

tcp_client.send(“Z \ r \ n”,0)

我有同样的问题,所以在读取套接字后,我必须通过执行以下操作显式删除“\ n”的最后一个实例:

 client_socket.gets.gsub(/\n$/, '')