通过UDP发送分成碎片的文件

2024-05-07 13:29:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在处理发送文件,该文件被分成用户在输入时设置的片段。问题是,我遇到了错误:

rec_list[fragIndex - 1] = dataIndexError: list assignment index out of range

我也发送单串信息,像在聊天,它正常工作。 我在我的代码中找不到bug,但也许你可以。在

顺便说一句,有些变量可能对数学有帮助,但可能并不适合。在

fragSize = 3

fragIndex = 216

fragCount = 215

问题是,碎片的总数应该是215(在发送之前预先计算过的-没问题),index不应该超过count!这就是问题所在。而且这不会发生在弦上。只有这里有文件。在

发送:

fragSize = int(input('Fragment size: ')) #max size of fragment
        while True:
            message = input('Enter message: ')
            fragIndex=0 #reset fragment indexing

    #asking for fragment size
            if(message[:3] == '-sf'):
                fragSize = int(input('Fragment size: '))

这里是发送文件的函数:

^{pr2}$

接收:

while True:
            received_chunks = 0
            rec_list = []
            while True:
                data, addr = sock.recvfrom(65535)
                header = data[:18]
                data = data[18:]
                (mType, fragSize, fragIndex, fragCount, crc) = struct.unpack('!hIIII', header)

                print(
                '\nTyp: ' + str(mType) +
                '\nFragSize: ' + str(fragSize) +
                '\nFragIndex: ' + str(fragIndex) +
                '\nFragCount: ' + str(fragCount) +
                '\nCRC: ' + str(crc)
                )

                if len(rec_list) < fragCount:
                    need_to_add = fragCount - len(rec_list)
                    rec_list.extend([''] * need_to_add)  # empty list for messages of size fragCount
                rec_list[fragIndex - 1] = data

                received_chunks += 1
                if received_chunks == fragCount:
                    break  # This is where the second while loop ends

只有当我想接收file类型的消息时才这样做:(因为它分为更多的消息类型)

if mType == 3:
     content = b''.join(rec_list)
     f = open('filename.py','wb')
     f.write(content)

Tags: 文件oftrueinputdatasizeiflist
1条回答
网友
1楼 · 发布于 2024-05-07 13:29:39

您试图比较apples to oranges。好吧,bytes到{},但维基百科没有对此做任何说明。在

while contents!='':
    ...

contentsbytes对象,''str对象。在Python3中,这两个东西永远不可能相等。发射炮弹我们看到了

^{pr2}$

因为所有对象都有一个真实性(即,bool(some_object)是有意义的)并且bytes对象在它们为空时会变成{},所以您可以这样做

^{3}$

更新

不是原始答案的一部分,但有人提出了一个关于将重试发送回客户端的问题。这里是服务器端的草图

while True:
            received_chunks = 0
            fragCount = -1
            rec_list = []
            while True:
                # wait forever for next conversation
                if fragCount == -1:
                    sock.settimeout(None)
                try:
                    data, addr = sock.recvfrom(65535)
                except socket.timeout:
                    # scan for blank slots in rec_list
                    retries = [i for i, data in rec_list if not data]
                    # packet is mType, numFrags, FragList
                    # TODO: I just invented 13 for retry mtype
                    sock.sendto(struct.pack("!{}h".format(len(retries+2)), 13,
                        len(retries), *retries)
                    continue
                # our first packet, set timeout for retries
                if fragCount == -1:
                    sock.settimeout(2)
                header = data[:18]
                data = data[18:]
                (mType, fragSize, fragIndex, fragCount, crc) = struct.unpack('!hIIII', header)

                print(
                '\nTyp: ' + str(mType) +
                '\nFragSize: ' + str(fragSize) +
                '\nFragIndex: ' + str(fragIndex) +
                '\nFragCount: ' + str(fragCount) +
                '\nCRC: ' + str(crc)
                )

                if len(rec_list) < fragCount:
                    need_to_add = fragCount - len(rec_list)
                    rec_list.extend([''] * need_to_add)  # empty list for messages of size fragCount
                rec_list[fragIndex - 1] = data

                received_chunks += 1
                if received_chunks == fragCount:
                    break  # This is where the second while loop ends

相关问题 更多 >