修剪从服务器套接字发送的文件大小

Prune file size sent from server socket

我正在连接到一个预配置的服务器,该服务器提供四种不同大小的文件格式。每个文件都附加了文件大小...

示例: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()

如果您能帮助我们减少文件的大小,我们将不胜感激!

Jason Harper 的建议 (@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!