我正在尝试通过套接字写入传输文件或数据块。我觉得好像我正在重新发明轮子,但我对一个简单的解决方案的搜索失败了(我发现的一切都太简单或太复杂)。服务器将在运行python 2.5.4的手机上运行。预期的应用是在电话和主机之间同步音乐文件。
这是我所拥有的内容,似乎有效。我发送并收到“确定”以分解流。
来回发送'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')
答案 0 :(得分:4)
来回发送'ok'基本上就像停止比特分手一样 数据流是一种合理的技术吗?
大多数协议使用一些终结器或其他终结器。流行的替代方案是'\ r \ n','\ r \ n \ r \ n'或EOF(ctrl + d),但这些只是任意选择,并且没有比你的'ok'更差或更好,只要你的客户和服务器知道如何处理它。
答案 1 :(得分:1)
答案 2 :(得分:1)
您的代码看起来不错。
您实际上不需要跨文件大小发送。您可以使用while True
,因为支票if not data: break
将停止循环。
while True:
data = s.recv(1024)
if not data: print " Done "; break
recvd += data
另外,你为什么发送'ok'是对方不检查它?你只是在每边跳过2个字节。
您不需要迎合多个客户吗?不需要多线程?
答案 3 :(得分:0)
rsync
是在两台计算机之间同步文件的标准方法。您可以像这样http://code.activestate.com/recipes/577518-rsync-algorithm/在Python中编写它,或者您可以像这样http://freshmeat.net/projects/pysync/包装C库,并进行一些调整,例如将MD4替换为MD5。
或者,如果你想在套接字级别这样做,你真的应该使用asyncore asynchat。这是一个用asynchat http://pyftpdlib.googlecode.com/svn-history/r20/trunk/pyftpdlib/FTPServer.py编写的FTP服务器,但你应该从阅读http://www.doughellmann.com/PyMOTW/asynchat/开始。注意关于消息终结点的部分2.很多网络协议都做这样奇怪的事情,即有时他们发送并接收全行命令和响应,有时它们发送和接收任意数据的块,前面是块中有多少字节的计数。使用asynchat可以更轻松地处理这个问题,并且您的程序也可以更好地扩展。