通过索引将输入片段保存到列表中并合并它们

时间:2016-10-29 20:04:47

标签: python list sockets udp

我正在使用自己的标题从一台PC向其他PC发送消息。用户可以设置消息的片段大小,这意味着我必须将消息分成片段并将它们发送到其他PC,我的代码应该有什么用处(没有测试因为接收是问题)。

现在,在接收方,我需要跟踪片段索引,总片段数以及我的标头中定义的一些其他内容,以检查可能的数据丢失,如(CRC)。但让我们回到这个问题。

我将每个收到的片段按其索引保存到list。我们假设标题中的第一个片段的index1,因此我想将第一个片段保存在位置1上。我一直这样做,直到我得到最后一个数据片段。但有些东西不能正常工作。最后,我想按照保存在列表中的顺序打印我收到的消息,从index 1开始直到最后使用''.join(list)

查看我的代码,它是打印出分成片段的邮件,或者当我移出print while周期时,它会打印任何内容,甚至不会Receive:信息。

发送:

def send_loop(self):
    global mType, fragSize, fragIndex, fragCount, crc
    mType=0
    fragSize=0
    fragIndex=0 
    fragCount=0 
    crc=0
    fragSize = int(input('Fragment size: ')) #max size of fragment
while True:
            message = input('Enter message: ')
    #sending text message
            if (message[:2] == '-m'):
                mType = 1 #text message
                if message.startswith('-m '):
                    message = message[3:] # remove "-m "
                fragCount = math.ceil(len(message) / fragSize)  #rounding up number of fragments to send

                while message!= '':
                    data = bytearray()
                    data.extend(message[:fragSize].encode('utf-8'))
                    fragIndex += 1
                    header = struct.pack('!hIIII', mType, fragSize, fragIndex, fragCount, crc)
                    self.sock.sendto(header + bytearray(data), (self.host, self.port))
                    message = message[fragSize:] #set start of message to the right by size of fragSize

接收:

def create_socket(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind((self.host, self.port))
        rec_list = []
        while True:
            data, addr = sock.recvfrom(65535)
            header = data[:18]
            data = data[18:]
            (mType, fragSize, fragIndex, fragCount, crc) = struct.unpack('!hIIII', header)

        #type of message is text
            if mType == 1:
                if len(rec_list) < fragCount:
                    rec_list = ['None'] * fragCount   #empty list for messages of size fragCount
                rec_list[fragIndex] = data.decode('utf-8') 


                print(
                    '\nTyp: '       + str(mType) + 
                    '\nFragSize: '  + str(fragSize) + 
                    '\nFragIndex: ' + str(fragIndex) + 
                    '\nFragCount: ' + str(fragCount) + 
                    '\nCRC: '       + str(crc)
                    )
                msg = ''.join(rec_list)
                print('\nReceived: ' +  msg) 

1 个答案:

答案 0 :(得分:0)

所以......在你的下方,我会找到一些能够永远倾听(第一个while True)的代码。我添加的是第二个while循环。当你收到某些东西时,你需要进入&#34;重建&#34;模式(进入第二个循环)并继续在那里,直到收到符合您的消息的所有块。

由于每个包中都会发送重建完整邮件所需的块总数,因此您可以使用该信息来了解重建邮件所需的部分数量。每次收到包时,这意味着您已收到一个块(并且该信息保存在received_chunks变量中)。

一旦收到与总块数相同的块数,就会知道您已重建消息,并且可以退出内部while以继续侦听下一条消息。

请注意,如果rec_list小于符合消息的片段总数,我也扩展。你可能不需要那样做,因为在进入内循环之前,它被初始化为一个空列表。在内循环中,您可以替换它:

if len(rec_list) < fragCount:
    need_to_add = fragCount - len(rec_list)
    rec_list.extend([None] * need_to_add)

由此:

if not rec_list:
    rec_list = [None] * fragCount

我这样做是为了避免偏离代码太多。你可以做更多的清理工作。我建议您执行更多print(来查看不同变量的状态以及发生了什么......

while True:
    received_chunks = 0
    rec_list = []
    # Let's start receiving chunks...
    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)
        )
        # type of message is text
        if mType == 1:
            if len(rec_list) < fragCount:
                need_to_add = fragCount - len(rec_list)
                rec_list.extend([None] * need_to_add)  # empty list for messages of size fragCount
            rec_list[fragIndex - 1] = data.decode('utf-8')
        print("We have received %s chunks. We expect a total of %s."
              " We are awaiting for %s chunks"
              % (received_chunks, fragCount, fragCount - received_chunks))
        received_chunks += 1
        if received_chunks == fragCount:
            break  # Get out of the second loop because we have all the chunks that we need.

        print("rec_list so far=%s" % (rec_list))
    # This is where the second (inner) while loop ends.

    print("Yay!! We got a FULL message...")
    msg = ''.join(rec_list)
    print('\nReceived: ' + msg)