【问题标题】:Python Sockets, requesting file from server then waiting to receive itPython Sockets,从服务器请求文件然后等待接收它
【发布时间】:2018-08-10 03:30:46
【问题描述】:

我正在尝试从我的客户端向我的服务器发送一个带有特定文件名的字符串,然后将该文件发送到客户端。由于某种原因,即使在收到所有文件后它也会挂起。它挂在:

m = s.recv(1024)

client.py

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.1.2", 54321))
s.send(b"File:test.txt")
f = open("newfile.txt", "wb")
data = None
while True:
    m = s.recv(1024)
    data = m
    if m:
        while m:
            m = s.recv(1024)
            data += m
        else:
            break
f.write(data)
f.close()
print("Done receiving")

server.py

import socket
import os

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 54321))

while True:
    client_input = c.recv(1024)
    command = client_input.split(":")[0]
    if command == "File":
        command_parameter = client_input.split(":")[1]
        f = open(command_parameter, "rb")
        l = os.path.getsize(command_parameter)
        m = f.read(l)
        c.sendall(m)
        f.close()

【问题讨论】:

  • 注意:您的服务器示例代码未显示如何从侦听套接字接受c

标签: python file sockets send recv


【解决方案1】:

TLDR

recv 阻塞的原因是因为在发送文件数据后套接字连接没有关闭。实现目前无法知道通信何时结束,这导致两个远程进程之间出现死锁。为避免这种情况,请关闭服务器中的套接字连接,这将在客户端生成文件结束事件(即recv 返回零长度字符串)。

更多见解

每当您设计任何两个进程相互通信的软件时,您都必须定义一个协议,以消除通信的歧义,以便双方始终准确地知道他们处于哪种状态。通常这涉及使用通信的语法来帮助指导数据的解释。

目前,您的实现存在一些问题:它没有定义适当的协议来解决潜在的歧义。当您考虑到一个对等方中对send 的每次调用不一定对应于另一个对等方中对recv 的一次调用时,这一点就变得很明显了。也就是说,对sendrecv 的调用不一定是一对一的。考虑在严重拥塞的网络上将文件名发送到服务器:当第一次调用recv 返回时,可能只有一半的文件名到达服务器。服务器无法(当前)知道它是否已完成接收文件名。在客户端也是如此:客户端如何知道文件何时完成?

要解决这个问题,我们可以在协议中引入一些语法,在服务器中引入一些逻辑,以确保在继续之前获得完整的文件名。一个简单的解决方案是使用 EOL 字符,即\n 来表示客户端消息的结尾。现在,在您的测试中,99.99% 的时间都需要一次调用 recv 才能读入。但是您必须预料到可能需要多次调用 recv 的情况。这显然可以使用循环来实现。

这个演示的客户端更简单。如果在发送文件后通信结束,则该事件可用于表示数据流的结束。当服务器端关闭连接时会发生这种情况。

如果我们要将实现扩展为允许对多个背靠背文件的请求,那么我们必须在协议中引入一些机制来区分一个文件的结尾和文件的开头下一个。请注意,这也意味着服务器可能需要缓冲它在先前迭代中读取的额外字节,以防出现重叠。流实现通常对这类事情很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2018-11-02
    相关资源
    最近更新 更多