Найти - Пользователи
Полная версия: через XML-RPC можно передавать файлы бльших размеров?
Начало » Python для экспертов » через XML-RPC можно передавать файлы бльших размеров?
1 2
o7412369815963
сабж
файлы 100Мб..20Гб
slav0nic
можно, но думаю не нужно) не думаю что SimpleXMLRPCServer пишет что-то на диск во временный каталог, небось всё в озу держит
Андрей Светлов
Даже если взять/создать реализацию протокола без ограничений по памяти - отсутствие докачки убьет идею на взлете.
К тому же не могу представить случай, где нужно проталкивать что-то гигабайтное через протокол передачи синхронных сообщений.
Ed
Я где-то что-то на эту тему встречал. Там как раз была реализация с передачей кусками и с докачкой.
Могу порыться в закромах, если надо.
o7412369815963
нашел в документации передачу файла от сервера клиенту, тут он сразу пишет в файл не накапливая в памяти
from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib

def python_logo():
with open("python_logo.jpg") as handle:
return xmlrpclib.Binary(handle.read())

server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(python_logo, 'python_logo')

server.serve_forever()
import xmlrpclib

proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
with open("fetched_python_logo.jpg", "w") as handle:
handle.write(proxy.python_logo().data)
o7412369815963
Андрей Светлов
Даже если взять/создать реализацию протокола без ограничений по памяти - отсутствие докачки убьет идею на взлете.
К тому же не могу представить случай, где нужно проталкивать что-то гигабайтное через протокол передачи синхронных сообщений.
мне для работы в локалке, возможно придется автоматизировать передачу толстых бекапов с хоста на хост.

а в стандартной поставке питона есть что-то для передачи толстых файлов?
сейчас делаю на сокетах
cybergrind
а чем плох какойнибудь nginx/apache/lighttpd + wget?

если нужен именно питон, можно конечно реализовать свой простейший протокол для передачи кусками.
чтото типа такого: http://sooda.dy.fi/ohjelmat/?id=SSFT
ZZZ
Я бы предложил ftp или tftp… ИМХО, они для этого и созданы.
evgenyl
на asyncore/asynchat думаю свой FTP не проблема написать, возможно таких поделок полно в нете
evgenyl
вот набросал побыстрому от безделия

server.py - принимает файлы
import asyncore
from struct import pack,unpack
import socket

TRANSFER_BUF_SIZE=1024*8

class Transfer(asyncore.dispatcher):
def __init__(self,sock,host):
asyncore.dispatcher.__init__(self,sock)
self.mode='head'
def handle_read(self):
if self.mode=='head':
try:
head_size=unpack('=H',self.recv(2))[0]
self.file_size, file_name=unpack('=Q%ss' % (head_size-8), self.recv(head_size))
self.file=open(file_name,'wb')
self.mode='data'
self.recived=0
except Exception, e:
print 'Bad head',e
self.close()
else:
buf=self.recv(TRANSFER_BUF_SIZE)
self.recived+=len(buf)
self.file.write(buf)
if self.recived==self.file_size:
self.close()

class TransferServer(asyncore.dispatcher):
def __init__(self, port=3333):
asyncore.dispatcher.__init__(self)
self.port = port
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.bind(("", port))
self.listen(5)
print 'server listed on %s port' % port
def handle_accept(self):
Transfer(*self.accept())

server=TransferServer()
asyncore.loop()
client.py - передает файл серверу
from struct import pack,unpack
import socket
from os.path import getsize

TRANSFER_BUF_SIZE=1024*8

fn='2.tgz'
rfn='1.tgz'
head=pack('=Q%ss' % len(rfn), getsize(fn), rfn )
file=open(fn)
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect( ('127.0.0.1', 3333) )
s.send(pack('=H',len(head)))
s.send(head)
while 1:
buf=file.read(TRANSFER_BUF_SIZE)
if buf=='': break
s.send(buf)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB