【问题标题】:Python sending mutliple strings using socket.send() / socket.recv()Python 使用 socket.send() / socket.recv() 发送多个字符串
【发布时间】:2016-03-10 19:33:38
【问题描述】:

我正在尝试使用 socket.send() 和 socket.recv() 函数发送多个字符串。

我正在构建一个客户端/服务器,并且“在一个完美的世界中”希望我的服务器在让我的客户端调用套接字时最多调用 socket.send() 函数 3 次(对于某个服务器命令) .recv() 调用 3 次。这似乎不起作用,客户端挂断等待另一个响应。

服务器:

        clientsocket.send(dir)
        clientsocket.send(dirS)
        clientsocket.send(fileS)

客户

response1 = s.recv(1024)
if response1:
    print "\nRecieved response: \n" , response1
response2 = s.recv(1024)
if response2:
    print "\nRecieved response: \n" , response2
response3 = s.recv(1024)
if response3:
    print "\nRecieved response: \n" , response3

我正在完成将所有字符串连接在一起然后在客户端中重新解析它们的繁琐任务,并且想知道是否有更有效的方法来做到这一点?

编辑: 我的 response1 输出给了我不寻常的结果。我第一次打印 response1 时,它会在 1 个字符串中打印所有 3 个响应(全部混合在一起)。我第二次调用它时,它自己给了我第一个字符串。以下对 recv 的调用现在出现故障/错误并显示第二个字符串,然后是第三个字符串。然后它开始显示其他命令,但好像它在队列中。

非常不寻常,但我可能会坚持在服务器中将字符串连接在一起,然后在客户端中解析它们

【问题讨论】:

    标签: python string sockets send


    【解决方案1】:

    这个问题的答案已经覆盖elsewhere

    您的问题有两种解决方案。

    解决方案 1: 标记字符串的结尾。 send(escape(dir) + MARKER) 然后您的客户继续调用 recv() 直到它获得消息结束标记。如果recv() 返回多个字符串,您可以使用标记了解它们的开始和结束位置。如果您的字符串包含标记,则需要转义该标记。记住也要在客户端上逃跑。

    解决方案 2: 在发送实际字符串之前发送字符串的长度。然后您的客户端继续调用 recv() 直到它读取所有字节。如果 recv() 返回多个字符串。你知道它们从哪里开始和结束,因为你知道它们有多长。发送字符串的长度时,让您使用固定数量的字节,以便您可以将字符串长度与字节流中的字符串区分开来。你会发现struct module很有用。

    【讨论】:

      【解决方案2】:

      您不会像在现实世界的应用程序中那样通过套接字发送字节/字符串。

      您将在套接字之上创建一个消息传递协议,然后将字节/字符串放入消息中并通过套接字发送消息。

      您可能也不会从头开始创建消息传递协议。你会使用像 nanomsgzeromq 这样的库。

      服务器

      from nanomsg import Socket, PAIR
      sock = Socket(PAIR)
      sock.bind('inproc://bob')
      sock.send(dir)
      sock.send(dirS)
      sock.send(fileS)
      

      客户

      from nanomsg import Socket, PAIR
      sock = Socket(PAIR)
      sock.bind('inproc://bob')
      response1 = sock.recv()
      response2 = sock.recv()
      response3 = sock.recv()
      

      在 nanomsg 中,recv() 将准确返回 send() 发送的内容,因此 send() 和 recv() 之间存在一对一的映射。在使用较低级别的 Python 套接字时情况并非如此,您可能需要多次调用 recv() 才能获取使用 send() 发送的所有内容。

      【讨论】:

        【解决方案3】:

        TCP 是一种流协议,没有消息边界。接收者不知道数据块是通过一个还是一百个send 调用发送的。您当然不能假设 3 个sends 可以与 3 个recvs 匹配。因此,您只剩下在接收器处重新组装片段的繁琐工作了。

        一种选择是在纯 TCP 流之上添加一个消息传递协议。这就是zeromq 所做的,它可能是减少乏味的一种选择。

        【讨论】:

          猜你喜欢
          • 2012-02-12
          • 1970-01-01
          • 2020-12-09
          • 1970-01-01
          • 2015-01-22
          • 1970-01-01
          • 1970-01-01
          • 2015-08-18
          • 1970-01-01
          相关资源
          最近更新 更多