Python套接字文件传输

10 投票
5 回答
29969 浏览
提问于 2025-04-16 22:19

我正在尝试通过一个套接字(socket)来传输文件或数据块。我感觉自己像是在重新发明轮子,但我找了很久也没找到一个简单的解决方案(我找到的要么太简单,要么太复杂)。这个服务器会在一部运行Python 2.5.4的手机上运行。我的目标是让手机和主电脑之间同步音乐文件。

这是我目前的代码核心部分,看起来是可以工作的。我通过发送和接收“ok”来分隔数据流。

来回发送“ok”作为停止信号来分隔数据流,这样的方法合理吗?

有没有标准的方法可以做到这一点?

在手机上运行任何类型的库服务器(比如ftp或http)并不是一个实用的解决方案,因为手机的内存和处理能力有限。

服务器:

import socket

c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
c.bind(('', 1234))
c.listen(1)
s,a = c.accept()

while True:
    data = s.recv(1024)
    cmd = data[:data.find('\n')]

    if cmd == 'get':
        x, file_name, x = data.split('\n', 2)
        s.sendall('ok')
        with open(file_name, 'rb') as f:
            data = f.read()
        s.sendall('%16d' % len(data))
        s.sendall(data)
        s.recv(2)

    if cmd == 'end':
        s.close()
        c.close()
        break

客户端:

import socket

s = socket.socket()
s.connect(('192.168.1.2', 1234))

def get_file(s, file_name):
    cmd = 'get\n%s\n' % (file_name)
    s.sendall(cmd)
    r = s.recv(2)
    size = int(s.recv(16))
    recvd = ''
    while size > len(recvd):
        data = s.recv(1024)
        if not data: 
            break
        recvd += data
    s.sendall('ok')
    return recvd

print get_file(s, 'file1')
print get_file(s, 'file2')
s.sendall('end\n')

5 个回答

1

有没有标准的方法来做到这一点?

有的。http://www.faqs.org/rfcs/rfc959.html

这个链接描述了标准的方法。

这里有一个实现的例子:http://docs.python.org/library/ftplib.html

2

你的代码看起来不错。

其实你不需要发送文件的大小。你可以用 while True 这个写法,因为 if not data: break 这个检查会让循环停止。

while True:
    data = s.recv(1024)

    if not data: print " Done "; break

    recvd += data

另外,为什么你要发送 'ok' 呢?对方又没有检查这个。这样你每一边都多了2个字节。

你难道不需要考虑多个客户端吗?不需要用多线程吗?

4

把“ok”来回发送作为停止位来分隔数据流,这样的做法合理吗?

大多数协议都会使用某种结束符。常见的选择有“\r\n”、“\r\n\r\n”或者EOF(按下ctrl+d),这些都是随便选的,并没有好坏之分,只要你的客户端和服务器知道怎么处理就行。

撰写回答