我有一个python线程套接字,在某一点上我有一个名为handleData的潜在递归函数(不确定它是否满足它的递归条件)。
def handleData(self, chunk):
current_chunk = self.last_chunk.get(threading.currentThread(), b'') # not sure thread id is safe to use, will be recycled
print('Last Chunk:', self.last_chunk.get(threading.currentThread(), b''))
print('Arg Chunk:', chunk)
current_chunk += chunk
print('Start Chunk:', current_chunk)
#data = enumerate(current_chunk) # Enumerate objs have no len and are not subscriptable (accessible through index positions)
#print('Enumerated Data:', data)
hash_dec = 35
doller_dec = 36
for idx, x in enumerate(current_chunk):
print('On idx:', idx, 'Byte', x)
if x == hash_dec and current_chunk[idx+1] == doller_dec and current_chunk[idx+2] == doller_dec:
start = idx+3
end = idx+44
if end >= len(current_chunk):
print('Index out of range')
self.last_chunk[threading.currentThread()] = current_chunk[idx:]
print('Last Chunk:', self.last_chunk[threading.currentThread()])
return
else:
record = current_chunk[start:end]
# do math get values
print('Printing Values')
self.printValues(record)
# need to save last chunk as everything after record
##self.last_chunk[threading.currentThread()] = current_chunk[end:]
##return
## THIS METHOD IS FAST when 48 bytes come in, does not work correctly for larger chunks
# or recursively call this function but make self.last_chunk = '' before hand
self.last_chunk[threading.currentThread()] = b''
if self.record_counter > 50:
exit()
print('Ending Chunk:', current_chunk[end:])
self.handleData(current_chunk[end:])
## Likely gets wasteful when chunks are 48 bytes because it will call itself with \n (110), get returned by the if, have more data again after being called again
对于代码中的无尽打印感到抱歉!
if记录> 50是因为这个递归函数变成了无限循环
套接字接收字节并传递给handleData。因此它有一个字节块可以进行操作,如果它成功地从字节中读取数据记录,它会将剩余的未读数据传回自身。
结果是它最后将最后一个字节传递给它自己,此时它应该意识到这里没有什么重要的,结束循环并让自己被一个新的chunk主套接字循环调用。
但是它反复遍历似乎不存在的数据及其列举的列表似乎导致了这一点,但我无法弄清楚原因。
这是一份印刷品,概述了我所解释的一切:
Chunk Length: 96
Last Chunk: b''
Arg Chunk: b'192#$$\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00192#$$\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00'
Start Chunk: b'192#$$\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00192#$$\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00'
On idx: 0 Byte 49
On idx: 1 Byte 57
On idx: 2 Byte 50
On idx: 3 Byte 35
Printing Values
0x0 0x0 0x0 0xff000000
Reader: 5888 Sensor: 87711 Age: 0xff000000 LastAge: 0xff000000 AgeDiff: 0x0 Record: 1
Ending Chunk: b'\x00192#$$\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00'
Last Chunk: b''
Arg Chunk: b'\x00192#$$\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00'
Start Chunk: b'\x00192#$$\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x01V\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00'
On idx: 0 Byte 0
On idx: 1 Byte 49
On idx: 2 Byte 57
On idx: 3 Byte 50
On idx: 4 Byte 35
Printing Values
0x0 0x0 0x0 0xfe000000
Reader: 5888 Sensor: 87711 Age: 0xfe000000 LastAge: 0xff000000 AgeDiff: -0x1000000 Record: 2
Ending Chunk: b'\x00'
Last Chunk: b''
Arg Chunk: b'\x00'
Start Chunk: b'\x00'
On idx: 0 Byte 0
On idx: 5 Byte 36
On idx: 6 Byte 36
On idx: 7 Byte 0
On idx: 8 Byte 0
On idx: 9 Byte 0
On idx: 10 Byte 0
On idx: 11 Byte 254
On idx: 12 Byte 0
On idx: 13 Byte 0
On idx: 14 Byte 0
On idx: 15 Byte 0
On idx: 16 Byte 0
On idx: 17 Byte 0
On idx: 18 Byte 1
On idx: 19 Byte 86
On idx: 20 Byte 159
On idx: 21 Byte 0
On idx: 22 Byte 0
On idx: 23 Byte 0
On idx: 24 Byte 0
On idx: 25 Byte 0
On idx: 26 Byte 0
On idx: 27 Byte 0
On idx: 28 Byte 0
On idx: 29 Byte 0
On idx: 30 Byte 0
On idx: 31 Byte 0
On idx: 32 Byte 0
On idx: 33 Byte 0
On idx: 34 Byte 0
On idx: 35 Byte 0
On idx: 36 Byte 0
On idx: 37 Byte 0
On idx: 38 Byte 0
On idx: 39 Byte 0
On idx: 40 Byte 0
On idx: 41 Byte 0
On idx: 42 Byte 0
On idx: 43 Byte 23
On idx: 44 Byte 0
On idx: 45 Byte 0
On idx: 46 Byte 0
On idx: 47 Byte 0
On idx: 48 Byte 0
On idx: 4 Byte 36
On idx: 5 Byte 36
On idx: 6 Byte 0
On idx: 7 Byte 0
On idx: 8 Byte 0
On idx: 9 Byte 0
On idx: 10 Byte 255
On idx: 11 Byte 0
On idx: 12 Byte 0
On idx: 13 Byte 0
On idx: 14 Byte 0
On idx: 15 Byte 0
On idx: 16 Byte 0
On idx: 17 Byte 1
On idx: 18 Byte 86
On idx: 19 Byte 159
On idx: 20 Byte 0
On idx: 21 Byte 0
On idx: 22 Byte 0
On idx: 23 Byte 0
On idx: 24 Byte 0
On idx: 25 Byte 0
On idx: 26 Byte 0
On idx: 27 Byte 0
On idx: 28 Byte 0
On idx: 29 Byte 0
On idx: 30 Byte 0
On idx: 31 Byte 0
On idx: 32 Byte 0
On idx: 33 Byte 0
On idx: 34 Byte 0
On idx: 35 Byte 0
On idx: 36 Byte 0
On idx: 37 Byte 0
On idx: 38 Byte 0
On idx: 39 Byte 0
On idx: 40 Byte 0
On idx: 41 Byte 0
On idx: 42 Byte 23
On idx: 43 Byte 0
On idx: 44 Byte 0
On idx: 45 Byte 0
On idx: 46 Byte 0
On idx: 47 Byte 0
On idx: 48 Byte 49
On idx: 49 Byte 57
On idx: 50 Byte 50
On idx: 51 Byte 35
Printing Values
0x0 0x0 0x0 0xfe000000
Reader: 5888 Sensor: 87711 Age: 0xfe000000 LastAge: 0xfe000000 AgeDiff: 0x0 Record: 3
Ending Chunk: b'\x00'
我需要改变将剩余数据传回函数的方式,以便我停止发送读取记录的最后一个字节(b'/ x00'),但我宁愿不做另一个if语句,任何想法?它需要传递剩余数据,因为当前块中还有另一条记录。
修改的 这可能是一个内存问题,我如何del在for循环语句中创建的枚举列表:(我会尝试分配给var并在删除它之前迭代它。
答案 0 :(得分:0)
这是一个递归编程问题。我只是将程序更改为自行返回而不是调用自身,并在基本情况下返回true(尽管我不认为真正的事情)。
我使用模块pdb(python debugger)来解决这个问题,非常好的工具!
我用vim运行代码:!python% 并使用pdb.set_trace()在函数的开头创建一个断点,我可以使用n(ext)逐步遍历每一行。
这让我看到它会回归多少次,我意识到我的问题:)
这是固定代码:
def handleData(self, chunk):
pdb.set_trace()
# Assigns the previous unprocessed byte string to the current_chunk, will be empty byte string if none found
current_chunk = self.last_chunk.get(threading.current_thread(), b'')
# Adds the argument chunk to the previous chunk (if called by itself or from main loop)
current_chunk += chunk
current_len = len(current_chunk)
# Decimal values of ASCII chars #, $
hash_dec = 35
dollar_dec = 36
idx = 0
# For loop to iterate over the byte string
for x in current_chunk:
# if current index is # and the next two indexs are $ then we have found a record delimiter
if x == hash_dec and current_chunk[idx+1] == dollar_dec and current_chunk[idx+2] == dollar_dec:
# Index positions for list slice
start = idx+3
end = idx+45
# if end slice index is greater than range of list
if end > current_len:
print('Index out of range')
self.last_chunk[threading.current_thread()] = current_chunk[idx:]
return True
self.printValues(current_chunk[start:end])
self.last_chunk[threading.current_thread()] = b''
#if end == current_len:
#print('No more bytes left in chunk!')
#return True
print('Ending Chunk:', current_chunk[end:])
return self.handleData(current_chunk[end:])
idx += 1
如果有人对此代码有任何其他想法,我很乐意听到它们! 块的大小直接传递到它可能必须通过自身返回到主循环的次数,所以我想将socket.recv()保持在低字节大小(4096 - 思考1024 )