代码之家  ›  专栏  ›  技术社区  ›  nathan

ruby tcpsocket写不起作用,但是puts写的起作用?

  •  6
  • nathan  · 技术社区  · 15 年前

    我正在使用gserver和tcpsocket开发RubyTCP客户机/服务器应用程序。我遇到了一个我不明白的问题。我的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. 写后刷新套接字不会改变行为。
    5 回复  |  直到 10 年前
        1
  •  4
  •   Duck    15 年前

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

        2
  •  4
  •   Greg    15 年前

    为了解决数据是否被发送的问题,在前面的文章中要注意缓冲,考虑使用类似的方法在线上捕获数据。 wireshark . 如果您发送的数据显示在线路上,则服务器没有接收到。

    否则,如果数据不在线路上,TCP可能会保留数据,以避免发送只有几个字节的单个段。( see Nagle's Algorithm )根据您的操作系统或TCP供应商的不同,您可能有不同的行为,但大多数TCP堆栈支持TCP_nodelay选项,这可能有助于以更及时的方式获取数据。

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

    这有助于调试,但如果吞吐量比响应优先级高,则通常不应留在生产代码中。

        3
  •  2
  •   Bkkbrad    15 年前

    尝试显式刷新:

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

    这样,输出最多只能缓冲到您决定发送它的点为止。

        4
  •  0
  •   acemutha    10 年前

    嗨,这里的原因应该与事实有关,把自动的lf和crl添加到您的字符串中。 如果您想使用发送或写入,您需要自己添加它们,例如:

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

        5
  •  0
  •   user2676180    10 年前

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

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