我一直在处理发送文件,该文件被分成用户在输入时设置的片段。问题是,我收到错误:
rec_list[fragIndex - 1] = data
IndexError: list assignment index out of range
我也在发送单个字符串消息,就像在聊天中一样,它正常工作。 我在代码中找不到错误,但也许你可以。
顺便说一下,有些变量可能对数学有帮助,但可能不适合。
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: '))
这里是发送文件的功能:
if (message[:2] == '-f'):
mType = 3
if message.startswith('-f'):
message = message[3:]
file_name = message
f=open(file_name,"rb")
contents = f.read()
fragCount = math.ceil(len(contents) / fragSize)
while contents!= '':
data = bytearray()
data.extend(contents[:fragSize])
fragIndex += 1
crc = crc32(data)
header = struct.pack('!hIIII', mType, fragSize, fragIndex, fragCount, crc)
self.sock.sendto(header + bytearray(data), (self.host, self.port))
contents = contents[fragSize:]
接收:
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
仅当我想接收文件类型的消息时:(因为它被分成更多的消息类型)
if mType == 3:
content = b''.join(rec_list)
f = open('filename.py','wb')
f.write(content)
答案 0 :(得分:1)
您尝试比较apples to oranges。好吧,bytes
到str
但是维基百科没有说明这一点。
while contents!='':
...
contents
是bytes
个对象,''
是str
个对象。在python 3中,这两件事永远不会是平等的。解雇shell我们看到了
>>> b''==''
False
>>>
>>> contents = b"I am the very model"
>>> while contents != '':
... if not contents:
... print("The while didn't catch it!")
... break
... contents = contents[3:]
...
The while didn't catch it!
由于所有对象都具有真实性(即bool(some_object)
有意义),而bytes
对象在空时转为False
,您可以这样做
while contents:
....
更新
不是原始答案的一部分,但提出了一个关于将重试发送回客户端的问题。服务器端在这里草拟
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