Во второй версии booboo
является зависимым именем , поэтому оно не отображается автоматически в шаблоне. Вы можете либо добавить using typename base<T>::booboo;
к производному классу, либо использовать ваше решение typedef, либо сказать typename base<T>::booboo bb = T(1);
.
Во-первых, в начальных recv
очевидно, что вы намеревались получить только начальный объект pickle, который вы использовали для кодирования длины оставшихся байтов. Однако, что recv
может также получить начальный сегмент оставшихся байтов (или даже всех оставшихся байтов, в зависимости от того, насколько он большой). Так сколько же вы должны дать начальному pickle.loads
?
Вам лучше создать поле фиксированной длины, которое будет содержать размер оставшихся данных. Это часто делается с помощью модуля struct
. На отправляющей стороне:
import struct
# Pickle the data to be sent
data = pickle.dumps(python_obj)
data_len = len(data)
# Pack data length into 4 bytes, encoded in network byte order
data_len_to_send = struct.pack('!I', data_len)
# Send exactly 4 bytes (due to 'I'), then send data
conn.sendall(data_len_to_send)
conn.sendall(data)
На принимающей стороне, как сказано в исключении, pickle.loads
принимает строку байтов, а не список. Поэтому частью решения этой проблемы будет объединение всех элементов списка в одну байтовую строку перед вызовом loads
:
unpickled = pickle.loads(b''.join(data))
Другие проблемы на принимающей стороне: используйте len(packet)
, чтобы получить размер буфера. sys.getsizeof
предоставляет внутреннюю память, используемую объектом bytes
, которая включает в себя неопределенные накладные расходы интерпретатора и здесь не то, что вам нужно.
После recv
первое, что вы должны сделать, это проверить наличие пустого буфера, который указывает конец потока (даже len(packet) == 0
или packet == ''
или not packet
). Это может произойти, например, если отправитель был убит до завершения отправки (или сбой сетевого соединения, или какая-то ошибка на стороне отправителя и т. Д.). В противном случае, если соединение заканчивается преждевременно, ваша программа никогда не достигнет break
и, следовательно, будет в очень узком бесконечном цикле.
Итак, в целом вы можете сделать что-то вроде этого:
# First, obtain fixed-size content length
buf = b''
while len(buf) < 4:
tbuf = recv(4 - len(buf))
if tbuf == '':
raise RuntimeError("Lost connection with peer")
buf += tbuf
# Decode (unpack) length (note that unpack returns an array)
len_to_recv = struct.unpack('!I', buf)[0]
data = []
len_recved = 0
while len_recvd < len_to_recv:
buf = self.s.recv(min(len_to_recv - len_recvd, BUFFERSIZE))
if buf == '':
raise RuntimeError("Lost connection with peer")
data.append(buf)
len_recvd += len(buf)
unpickled_obj = pickle.loads(b''.join(data))
РЕДАКТИРОВАТЬ: перенесены круглые скобки