Python套接字文件传输
我正在尝试通过一个套接字(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),这些都是随便选的,并没有好坏之分,只要你的客户端和服务器知道怎么处理就行。