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

Prune file size sent from server socket

提问人:Stryker2k2 提问时间:11/6/2019 最后编辑:Stryker2k2 更新时间:11/6/2019 访问量:49

问:

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

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

任何从文件中修剪大小的帮助将不胜感激!

python 套接字 jpeg recv

评论

0赞 jasonharper 11/6/2019
必须有一个控制字符或其他一些长度结束位置的指示,否则这个问题在物理上是不可能解决的。打印第一个数据块以查看实际存在的内容。repr()
0赞 Stryker2k2 11/6/2019
@jasonharper:这让我找到了某个地方!在随机文本.txt文件...repr() 的输出是,所以也许我可以用它做点什么!'457''11111111111111111111111

答:

0赞 Stryker2k2 11/6/2019 #1

杰森·哈珀(Jason Harper)的建议(@jasonharper)引起了我的思考。当我对 randomText.txt 中的块运行 repr(data) 时,我看到它有一个中断,看起来像......

'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!