首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python使用socket.send() / socket.recv()发送多个字符串

Python使用socket.send() / socket.recv()发送多个字符串
EN

Stack Overflow用户
提问于 2015-12-06 00:25:28
回答 3查看 7.3K关注 0票数 0

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

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

服务器:

代码语言:javascript
运行
复制
        clientsocket.send(dir)
        clientsocket.send(dirS)
        clientsocket.send(fileS)

客户端

代码语言:javascript
运行
复制
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时,它会将所有3个响应打印成一个字符串(全部合并在一起)。第二次我叫它的时候,它给了我第一个字符串。下面对recv的调用现在出现故障/窃听,并显示第二个字符串,然后显示第三个字符串。然后它开始显示其他命令,但就好像它在后面和队列中一样。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-06 00:43:16

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

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

您可能也不会从头开始创建消息传递协议。您可以使用像奈米零q这样的库。

服务器

代码语言:javascript
运行
复制
from nanomsg import Socket, PAIR
sock = Socket(PAIR)
sock.bind('inproc://bob')
sock.send(dir)
sock.send(dirS)
sock.send(fileS)

客户端

代码语言:javascript
运行
复制
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()发送的所有信息,但情况并非如此。

票数 2
EN

Stack Overflow用户

发布于 2015-12-06 00:40:17

TCP是一种流协议,没有消息边界。接收方不知道是否用一个或100个send调用发送了大量数据。当然,您不能假设3 sends可以与3recv相匹配,因此,您需要在接收端重新组装碎片的繁琐工作。

一种选择是在纯TCP流之上分层消息传递协议。这就是零q所做的,它可能是减少单调乏味的一种选择。

票数 1
EN

Stack Overflow用户

发布于 2015-12-06 04:52:22

对此的答案已经在其他地方中讨论过了。

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

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34112551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档