Не просто записывайте сериализованные данные в сокет. Сначала отправьте поле фиксированного размера, содержащее длину сериализованного объекта.
Отправляющая сторона примерно:
socket.write(struct.pack("H", len(data)) #send a two-byte size field
socket.write(data)
И возвращающаяся сторона становится чем-то вроде:
dataToRead = struct.unpack("H", socket.read(2))[0]
data = socket.read(dataToRead)
Это общий шаблон проектирования для программирования сокетов. Большинство проектов расширяют проводную структуру, чтобы включить поле типа, так что ваша принимающая сторона становится чем-то вроде:
type = socket.read(1) # get the type of msg
dataToRead = struct.unpack("H", socket.read(2))[0] # get the len of the msg
data = socket.read(dataToRead) # read the msg
if TYPE_FOO == type:
handleFoo(data)
elif TYPE_BAR == type:
handleBar(data)
else:
raise UnknownTypeException(type)
В результате вы получаете формат сообщения по проводам, который выглядит следующим образом:
struct {
unsigned char type;
unsigned short length;
void *data;
}
Это делает разумную работу по защите будущего протокола от непредвиденных требований. Это протокол Type-Length-Value , который вы найдете снова и снова и снова в сетевых протоколах.