dimanche 4 avril 2021

Python Socket TCP truncates message

I have a communication system where every user has a tcp server and client. I have to computers that I use to test my system. The idea is that one user requests info from the other one and then receives that info. But when I do it from computer 1 to 2 it works, however the other way around does not work, the info is truncated. Here is the relevant code :
server.py

def handle_client(conn, addr):
connected = True

while connected:
    msg_length = conn.recv(HEADER).decode(FORMAT)

    if msg_length:
        msg_length = int(msg_length)
        msg = conn.recv(msg_length).decode(FORMAT)

        if msg == DISCONNECT_MESSAGE:
            connected = False

        elif msg == "REQBLOCKCHAIN":
            print(f"Blockchain request from {addr}")
            addr_s = addr[0]
            print(addr_s)
            conn.send("Chain successfully requested.".encode(FORMAT))
            send_chain(addr_s)
            

        elif msg == "BLOCKCHAIN":
            print(f"Blockchain received from {addr}")
            print(threading.active_count())
            chain_length = conn.recv(HEADER).decode(FORMAT)

            if chain_length:
                chain_length = int(chain_length)
                chain_recv = conn.recv(chain_length)
                print("b")
                print(chain_recv)
                chain = chain_recv.decode(FORMAT)
                print(chain_length)
                print(chain)
                print(len(chain_recv))
                chain_dict = json.loads(fix_text(chain))
                print(chain_dict[-1])
                chain_is_valid = is_chain_valid(chain_dict)
                if chain_is_valid:
                    try:
                        with open("data/blockchain.json") as og_chain_file:
                            og_chain = json.load(og_chain_file)
                        if og_chain == chain_dict:
                            conn.send("Same".encode(FORMAT))
                            return "Same"
                        else:
                            if og_chain[-1]['index'] < chain_dict[-1]['index']:
                                with open("data/blockchain.json", "w") as chain_file:
                                    json.dump(chain_dict, chain_file)
                                conn.send("Chain successfully broadcasted.".encode(FORMAT))
                                return "Blockchian updated"
                            else:
                                conn.send("Same or newer".encode(FORMAT))
                                return "Same or newer"
                    except FileNotFoundError:
                        conn.send("Blockchain data file missing".encode(FORMAT))
                        return "Blockchain data file missing"
                else:
                    err = {'message' : 'Received chain is not valid !',
                           'ip_sender': addr[0]}
                    conn.send(json.dumps(err).encode(FORMAT))
                    return err
conn.close()

client.py

def req_blockchain(addr):
    HEADER = 64
    PORT = 5050
    FORMAT = 'utf-8'
    ADDR = (addr, PORT)

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(ADDR)


    msg_length = len("REQBLOCKCHAIN")
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send("REQBLOCKCHAIN".encode(FORMAT))
    print(client.recv(2048).decode(FORMAT))

def send_chain( addr):
    HEADER = 64
    PORT = 5050
    FORMAT = 'utf-8'
    ADDR = (addr, PORT)
    print(ADDR)

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(ADDR)

    msg_length = len("BLOCKCHAIN".encode(FORMAT))
    send_type_length = str(msg_length).encode(FORMAT)
    send_type_length += b' ' * (HEADER - len(send_type_length))
    print(send_type_length.decode(FORMAT) + "ok")
    client.send(send_type_length)
    client.send("BLOCKCHAIN".encode(FORMAT))
    with open("data/blockchain.json") as chain_file:
        chain = json.load(chain_file)
    chain_se = json.dumps(chain)
    print(chain_se)
    chain_msg = chain_se.encode(FORMAT)
    msg_length = len(chain_msg)
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send(chain_msg)
    print(client.recv(2048).decode(FORMAT))

I have a ton of print statements for debugging, basically the length is good, but the message is truncated. Computer 1 calls the function req_blockchain to computer 2 and then everything is automatic. Works with 1 requesting from 2 but not the other way around which is strange. And the place where the info is cut changes every time. On the sending end, the message is full, on the receiving end the message is truncated.

Any help is appreciated :)




Aucun commentaire:

Enregistrer un commentaire