使用Python在套接字上发送文件仅在强制关闭套接字后才能工作

时间:2017-05-30 01:02:03

标签: python python-2.7 file sockets

我正在尝试通过Python 2.7.x中的套接字发送文件。我的客户端和服务器代码如下。它正常工作,但只有在客户端连接终止套接字后才能运行。所以我将raw_input('finished')添加到两者的末尾以进行调试。

所以,如果我启动服务器,然后运行客户端...看起来除了文件的最后一位之外的所有内容都发送,直到我强行杀死客户端然后它就在那里。所以问题肯定在服务器循环中......我只是不知道如何解决它。 if not data: break未被触发。但是,如果我执行if len(data) < 1024: break之类的操作,它将无法用于更大的文件。

感谢任何帮助!

# client.py

import socket

conn = socket.socket()
conn.connect(('localhost', 1337))

f = open('test.jpg', 'rb')
data = f.read(1024)
while data:
    conn.send(data)
    data = f.read(1024)
f.close()

raw_input('finished')
# server.py

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('localhost', 1337))
s.listen(5)
conn, addr = s.accept()

f = open('test.jpg', 'wb')
while True:
    data = conn.recv(1024)
    if not data:
        break
    f.write(data)
f.close()

raw_input('finished')

1 个答案:

答案 0 :(得分:2)

来自您发布的代码:

while data:
   conn.send(data)
   data = f.read(1024)

来自Python socket documentation

socket.send(string[, flags])
[...]
Returns the number of bytes sent. Applications are responsible for checking 
that all data has been sent; if only some of the data was transmitted, the 
application needs to attempt delivery of the remaining data.

那应该告诉你问题是什么,但只是要明确一下:send()可能会也可能不会接受你要求它在返回之前发送的所有字节,并且它取决于你在它只接受第一个(n个)字节而不是整个缓冲区的情况下正确处理它。如果你没有检查send()的返回值,那么你有时会在不知道的情况下丢弃文件的一些字节。您需要检查send()的返回值,如果它小于len(数据),则再次使用剩余字节调用send()(根据需要多次)。或者你可以调用conn.sendall()而不是conn.send(),因为sendall()会为你执行那个逻辑。