WedX - журнал о программировании и компьютерных науках

Отправка больших файлов в Twisted

У меня есть очень простой код, который позволяет мне отправлять изображение с клиента на сервер. И это работает.

Вот так просто:

На стороне клиента...

    def sendFile(self):
        image = open(picname)
        data = image.read()
        self.transport.write(data)

На стороне сервера...

    def dataReceived(self, data):
        print 'Received'
        f = open("image.png",'wb')
        f.write(data)
        f.close()

Проблема в том, что это работает только в том случае, если размер изображения составляет до 4.somethingkB, поскольку он перестает работать, когда изображение становится больше (по крайней мере, не работает, когда достигает 6kB). Затем, когда я вижу, что «Получено» печатается более одного раза. Это заставляет меня думать, что данные разделяются на более мелкие куски. Однако, даже если эти фрагменты данных попадают на сервер (поскольку я вижу повторную печать, вызванную из dataReceived), изображение повреждено и не может быть открыто.

Я не очень разбираюсь в протоколах, но я предположил, что TCP должен быть надежным, поэтому тот факт, что пакеты попали туда в другом порядке или около того, не должен... случиться? Поэтому я подумал, что, возможно, Twisted делает что-то, что я игнорирую, и, возможно, мне следует использовать другой протокол.

Вот мой вопрос. Есть ли что-то, что я мог бы сделать сейчас, чтобы заставить его работать, или мне определенно следует перейти на другой протокол? Если да... есть идеи? Моей целью было бы отправить изображение большего размера, может быть, порядка сотен килобайт.

10.11.2015

  • Вы должны отправить его в блоках. Держите файл открытым на принимающей стороне и записывайте каждый блок по мере его поступления. Он может поступать блоками разного размера. 11.11.2015
  • Чтобы отправлять его блоками, вы можете использовать протокол FileSender (twistedmatrix.com/documents/15.4.0/api/) filesender = basic.FileSender() filesender.beginFileTransfer(data, self.transport) 12.11.2015

Ответы:


1

Это вариант записи в Twisted FAQ:

TCP — это потоковый протокол. Он доставляет поток из байтов, который может быть разбит на произвольное количество фрагментов. Если вы записываете один большой блок байтов, он может быть разбит на произвольное количество меньших фрагментов, в зависимости от характеристик вашего физического сетевого подключения. Когда вы говорите, что TCP должен быть "надежным" и что порции должны приходить по порядку, вы примерно правы: однако по порядку прибывают байты, а не порции.

То, что вы делаете в своем методе dataReceived, заключается в том, что после получения каждого фрагмента вы открываете файл и записываете содержимое только этого фрагмента в "image.png", а затем закрываете его. Если вы измените его, чтобы открыть файл в connectionMade и закрыть файл в connectionLost, вы должны хотя бы смутно увидеть правильное поведение, хотя это все равно приведет к повреждению / обрезанию изображений, если соединение неожиданно потеряно без предупреждения. Вам действительно следует использовать протокол кадрирования, такой как AMP; хотя, если вы просто отправляете большие блоки данных, HTTP, вероятно, является лучшим выбором.

11.11.2015
  • Привет @Glyph, спасибо за ответ. Я попробовал метод connectionMade - connectionLost, и он сработал хорошо, хотя... думаю, если мне нужна надежная структура, я не должен его использовать. Я хотел бы объединить эту функцию с более крупным проектом, который у меня есть, который использует протокол TCP, поэтому, если бы я мог избежать изменения всего этого кода, было бы здорово. Было бы хорошим вариантом отправить его блоками, как предложил @MartinEvans? Или это все еще будет противоречить какому-то внутреннему механизму Twisted? Спасибо еще раз! 11.11.2015
  • @josepmeg - похоже, вам следует задать еще один вопрос - заполнить весь ответ в поле для комментариев здесь было бы сложно :). Когда вы задаете новый, обязательно укажите, каковы ваши требования и почему они такие, какие они есть, потому что я не уверен, что полностью понимаю, что это за код, здесь. 13.11.2015
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]