python套接字文件传输

时间:2011-07-26 21:28:22

标签: python sockets file-transfer

我正在尝试通过套接字写入传输文件或数据块。我觉得好像我正在重新发明轮子,但我对一个简单的解决方案的搜索失败了(我发现的一切都太简单或太复杂)。服务器将在运行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')

4 个答案:

答案 0 :(得分:4)

  

来回发送'ok'基本上就像停止比特分手一样   数据流是一种合理的技术吗?

大多数协议使用一些终结器或其他终结器。流行的替代方案是'\ r \ n','\ r \ n \ r \ n'或EOF(ctrl + d),但这些只是任意选择,并且没有比你的'ok'更差或更好,只要你的客户和服务器知道如何处理它。

答案 1 :(得分:1)

  

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

是。 http://www.faqs.org/rfcs/rfc959.html

描述了执行此操作的标准方法。

以下是一项实施:http://docs.python.org/library/ftplib.html

答案 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可以更轻松地处理这个问题,并且您的程序也可以更好地扩展。