在Python中通过套接字发送的字符串将不会与等效字符串一次比较.recv' d

时间:2015-10-09 07:08:03

标签: python sockets

忽略更大范围的代码,有一个特定部分无法正常工作。

我通过TCP向客户端发送来自客户端的文件的GET请求。我在服务器端打开文件(在这种特殊情况下为.html),读取它并将文件发送到客户端。客户端应该接收,直到文件传输完成,然后继续下一步,即解析HTML文件并发送后续请求。

无效的部分是接收结束消息。我试过发送一个明确的" END"完成发送HTML文件后的消息,我尝试发送一个空字符串。有问题的是,当客户端收到结束消息时,它是否是一个字符串,如" END"或空,它没有正确比较。在if语句中比较它时,对客户端的终止消息执行.strip()没有帮助。请参阅以下代码段。

server.py

##socket setup and file open/read
while True:
    conn.send(buffer)
    buffer = htmlFile.read(1460)
    if buffer == "":
        conn.send("END")
        break

client.py

##socket setup and GET request send
while True:
    chunk = clientSocket.recv(1500)
    if chunk == "END":
        break
    else:
        total = total + chunk
print "received all chunks"

我希望一旦文件传输在服务器端完成,就可以发送" END"。它就是这样。当我让客户打印出它收到的每个块时,它将完美地打印出整个HTML文件,然后添加" END"到它,然后回到上面列出的.recv()行。

为什么一旦"结束"它就不会突破这个接收循环。如果收到消息?

如果需要,我可以包含更多代码,但我非常有信心其余的工作正常,考虑到client.py正确打印HTML代码,并且显然正在接收" END"信息。由于某种原因,它不会被if抓住......

v2.7.10,如果重要的话,在虚拟机中运行最新的Ubuntu。

1 个答案:

答案 0 :(得分:3)

TCP不保留通过套接字发送的消息的边界。消息可以相互粘连或分成几个消息。 N send命令并不意味着您需要N recv。由应用程序协议级别决定将接收到的数据分离为消息。

在您的情况下,您会收到END消息以及文​​件的最后一部分。 为了解决这个问题,你可以从这开始:if chunk.endswith("END"):(如果你没有在文件之后发送任何内容,那么END确实会在最后) 和this link about TCP message framing