import socket

# Tâche 0.1.
def recv_exactly (s, taille_exacte):
    res = b''
    while len (res) < taille_exacte:
        morceau = s.recv (taille_exacte - len (res))
        res = res + morceau
    return res

nb_octets_de_lentete = 10

# Tâche 1.0
def make_client_socket (server_host, server_port):
    s = socket.socket ()
    s.connect ((server_host, server_port))
    return s

# Tâche 1.1
def make_server_socket (server_port):
    s = socket.socket ()
    s.bind (('', server_port))
    s.listen ()
    return s

# Étant donné un entier, renvoie un bytes de taille
# constante encodant l'entier.
def int_to_bytes (i):
    res = str (i).encode ()
    while len (res) < nb_octets_de_lentete:
        res = b'0' + res
    return res

# Étant donné un bytes de taille contante, renvoie l'entier
# encodé dedans.
def bytes_to_int (bb):
    return int (bb)

# Étant donné un entier Python, envoie sur le socket donné
# un entête de taille fixe contenant l'entier.
def send_header (s, nb_octets_du_contenu):
    header = int_to_bytes (nb_octets_du_contenu)
    s.sendall (header)

# Renvoie le contenu (un nombre d'octets), en tant qu'un
# entier Python, de l'entête de taille fixe reçue sur s.
def receive_header (s):
    header = recv_exactly (s, nb_octets_de_lentete)
    return bytes_to_int (header)

# Tâche 1.2a
def send (s, contenu):
    nb_octets_du_contenu = len (contenu)
    send_header (s, nb_octets_du_contenu)
    s.sendall (contenu)

# Tâche 1.2b
def receive (s):
    nb_octets_du_contenu = receive_header (s)
    return recv_exactly (s, nb_octets_du_contenu)
