Сократить размер файла, отправленного с сокета сервера - PullRequest
0 голосов
/ 05 ноября 2019

Я подключаюсь к предварительно настроенному серверу, который обслуживает четыре разных формата файлов с разными размерами. Каждый файл добавляется с размером файла ...

Пример: lighthouse.jpg

561276ÿØÿà JFIF  ` `  ÿî Adobe

«561276» - это размер файла, который необходимо удалить перед сохранением файла.

Пример: randomText.txt

45711111111111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222222222222
33333333333333333333333333333333333333333333333333
44444444444444444444444444444444444444444444444444444444
66666666666666666666
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cvccccccccccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddddddddddddddd

«457» - это размер файла, который необходимо удалить перед сохранением файла.

Некоторые файлы имеют размер, равныйдлиной всего 3 цифрыУ некоторых размер файла составляет 6 цифр (как видно здесь). Я хочу сделать мой код независимым от размера;независимо от того, сколько цифр имеет размер.

Я пытался использовать:

    while len(buf) < 4:
        buf += sock.recv(4 - len(buf))
    size = struct.unpack('!i', buf)

, но это только сокращает первые четыре цифры.

И

Я пытался использовать

len = sock.recv(4)
data = sock.recv(len)

, но еще раз ... только сокращает первые четыре цифры

Вот что у меня есть:

def get_size():
    buf = ''
    while len(buf) < 4:
        buf += sock.recv(4 - len(buf))
    size = struct.unpack('!i', buf)
    print "[*] Receiving %s bytes" % size


def download_pic():

    size = get_size()
    fname = 'tst.jpg'

    with open(fname, 'wb') as img:
        while True:
            data = sock.recv(1024)
            if not data:
                break
            img.write(data)
    print '[*] {0} received!'.format(fname)


def main():
    doconnectionstuffandprinttoconsole() #establishes connection

    answer = input("[>] Your Selection: ")
    sock.send(str(answer))

    if answer == 2:
        download_pic()

    sock.close()

Любая помощь в сокращении размера из файла (-ов) будет принята с благодарностью!

1 Ответ

0 голосов
/ 05 ноября 2019

предложение Джейсона Харпера (@ jasonharper) заставило меня задуматься. Когда я запустил repr (data) для фрагментов из randomText.txt , я увидел, что в нем был разрыв, похожий на ...

'457''1111111111111111111111...

Сервер пытался отправить два разных чанка (по одному за раз), но продолжал объединяться в один чанк. Итак, я увеличил свой sock.recv (64) до sock.recv (256). И по какой-то причине он отправляет два куска!

'457'
'111111111...' [truncated]

НОВЫЙ И УЛУЧШЕННЫЙ КОД!

import socket
import sys
import struct
import os

user1 = {'user1': 91827364}
user2 = {'user2': 19283746}
user3 = {'user3': 46372819}

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.connect(('127.0.0.1', 2058))


def print_data():
    data_rcv = sock.recv(1024)
    print "[-] {0}".format(data_rcv)


def download_file(format):
    fname = 'download'
    fullname = fname + '.' + format

    try:
        with open(fullname, 'wb') as txt:
            len = sock.recv(256)
            while True:
                data = sock.recv(int(len))
                if not data:
                    break
                txt.write(data)
        print("[*] {0} successfully downloaded with a length of {1} characters!".format(fullname, len))
    except Exception:
        print("[!] Error receiving file.  Please try again.")


def connect():
    print("[*] Sending Length")
    sock.send("5")

    my_struct = struct.pack('5s i', 'user1', 91827364)
    print("[*] Sending User1 Struct")
    sock.send(my_struct)

    print_data()


def main():
    print_data()
    connect()

    print_data()

    answer = input("[>] Your Selection: ")
    sock.send(str(answer))

    if answer == 2:         # Option to download Lighthouse.jpg
        download_file("jpg")
    elif answer == 4:       # Option to download randomText.txt
        download_file("txt")

    sock.close()


if __name__ == "__main__":
    main()

МОЙ ВЫХОД

[-] Please enter credentials
[*] Sending Length
[*] Sending User1 Struct
[-] Authenticated
[-] Choose a file to retrieve from the following list (enter the number):
 1. photo.png
 2. Lighthouse.jpg
 3. npp.6.8.5.Installer.exe
 4. randomText.txt
[>] Your Selection: 2
[*] download.jpg successfully downloaded with a length of 561276 characters!
...