Serialisation: Protocol Buffers


Compiling prototype files

The Python files are generated from the prototype by

      protoc personv3.proto --python_out=python

When I tried to compile my client (see later), I got the error

      AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'
I am now using the 3.12.2 version of protoc. It seems that the version installed in Python 3.6 (version 3.11.2) isn't quite compatable with this. I had to do

pip3 uninstall protobuf
pip3 install protobuf
to get the versions right.

Structure of files

The compiler just creates one file. However, it isn't nice to look at, as it uses Python meta-calls to generate classes. However, you can write programs assuming that it has generated standard Python classes.

For the example we use, the classes are Person, Person.Name and Person.Email.

Person client

The client creates a Person and then fills in the fields. To add a Name there are two ways: create a Name object, assigns its fields and then copy its value into the Person.Name by CopyFrom(), or assign the fields of Person.Name directly. For the list of emails, add() new emails and fill in the fields of each email.

The client is

import socket
import fileinput
import sys

import personv3_pb2

PORT = 2001

if len(sys.argv) < 2:
    print('Usage: comm hostname')

host = sys.argv[1]

person = personv3_pb2.Person()

#name = person.Name() = 'Newmarch'
#name.personal = 'Jan' = 'Newmarch' = 'Jan'

email1 =
email1.kind = 'private'
email1.address = ''

email2 =
email2.kind = 'work'
email2.address = ''


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((host, PORT))


Person server

The server listens for client connections and reads the data. It creates a Person object and then calls the method ParseFromStrin() on the (binary) data. Here the servers just prints the created person and terminates the connection.

The server is

# sequential server

import socket
import personv3_pb2

PORT = 2001

with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    while True:
        conn, addr = s.accept()
        with conn:
            print('Connected by', addr)
            while True:
                data = conn.recv(1024)
                if not data:
                person = personv3_pb2.Person()

Copyright © Jan Newmarch,
Creative Commons License
" Network Programming using Java, Go, Python, Rust, JavaScript and Julia" by Jan Newmarch is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License .
Based on a work at .

If you like this book, please contribute using PayPal