Python使用socket.send()/ socket.recv()

时间:2015-12-06 00:25:28

标签: python string sockets send

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

我正在构建一个客户端/服务器,并且在一个完美的世界中#34;我希望我的服务器最多调用socket.send()函数3次(对于某个服务器命令),同时让我的客户端调用socket.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的调用现在是glitched / bugged并显示第二个字符串,然后显示第三个字符串。然后它开始显示其他命令,但好像它在后面并在队列中。

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

3 个答案:

答案 0 :(得分: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()发送的所有内容。

答案 1 :(得分:1)

TCP是一种流协议,没有消息边界。接收方是否知道是否通过一个或一百个send呼叫发送了一团数据。您当然不能假设3 sends可与3 recv匹配。所以,你在接收器处重新组装片段是一项繁琐的工作。

一种选择是在纯TCP流之上层叠消息传递协议。这就是zeromq的作用,它可能是减少乏味的一种选择。

答案 2 :(得分:1)

此问题的答案已涵盖elsewhere

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

解决方案1 ​​: 标记字符串的结尾。 send(escape(dir) + MARKER)然后,您的客户端会一直致电recv(),直到它收到消息结束标记。如果recv()返回多个字符串,则可以使用标记来了解它们的起点和终点。如果您的字符串包含标记,则需要转义标记。记得在客户端逃脱。

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