[Tutor] Sending Pickled Data from Server to Client via Sockets

Peter Otten __peter__ at web.de
Tue Apr 14 11:36:53 EDT 2020


Christian Liz-Fonts wrote:

> I first tried

This looks like an unfiltered brain dump.

If you want to do this as an exercise I suggest that you start with 
something that works (like the echo client/server example in the socket 
library documentation), and then add features.

If it's not an excercise, consider something ready-to-use, like, maybe
https://pyro4.readthedocs.io/en/stable/intro.html

> 
> message = pickle.dumps(s2)
> cs.sendall(message)
> 
> on my server and for my client
> 
> msg = ns.recv(32,768)

For those who are not an expert: what does that 768 mean?

> this returned
> 
> msg = ns.recv(32,768) OSError: [WinError 10045] The attempted operation is
> not supported for the type of object referenced
> 
> 
> So I then tried, my server being
> 
> 
> HL = 10
> ...
> 
> message = pickle.dumps(s2)
> 
> message_header - bytes(f"{len(message):<{HL}}", "utf-8")+messae

Please always cut and paste the code you are actually using.

> 
> cs.send(message_header + message)
> 
> and this being my client
> 
> while True:
>     full_msg = b''
>     new_msg = True
>     while True:
>          msg = ns.recv(16)
>          if new_msg:
>              print("new msg len:", msg[:HL])
>              msglen = int(msg[:HL])
>              new_msg = False
>          print(f"full message length: {msglen}")
>          full_msg += msg
>          print("adding other parts together")
>          print(len(full_msg))
>          if len(full_msg)-HL == msglen:
>              new_msg = True
>              full_msg = b""
>              print("full msg recvd") print(full_msg[HL:])
> 
> 
> this returned
> 
> new msg len: b'5575 '
> 
> then it printed out
> 
> full message length: 5575
> adding other parts together
> 16
> 
> until reaching
> 
> full message length: 5575
> adding other parts together
> 11160
> 
> as you can imagine my log is a bit lengthy as it is going up by 16 bytes
> each time. 

The 16 bytes seem to be your choice, no one is stopping you from specifying 
17, say ;)

> Also it seems as if the last is statement does not run
> 
> if len(full_msg)-HL == msglen:
> 
> I imagine this is because len(full_msg)-HL is exceeding msglen?

That would be my guess, too.

> what should I do was the first direction I was heading in the correct one
> or the second? I am sending and receiving files between my own clients to
> my host so no other person will be sending data to me so it does not need
> to be secure, I just need to most efficient method to do what I need to do
> have been trying to correct this error for 36 hours and decided to give
> this a try. Please advice me on how to proceed.

I seems like you want to send a succession of 

length-of-data pickled-data pairs

and are stuck on how to break these apart. To debug your problem you do not 
need the client/server infrastructure. Just make some test data and a mock 
connection:

import pickle

DIGITS = 10


def format_record(record):
    item = pickle.dumps(record)
    data =  b"%*d%s" % (DIGITS, len(item), item)
    assert len(data) == DIGITS + len(item)
    return data


class Conn:
    def __init__(self):
        self.pos = 0
        records = ((i, "Hello World", 42.0) for i in range(100))
        self.data = b"".join(format_record(record) for record in records)

    def recv(self, size):
        result = self.data[self.pos:self.pos + size]
        self.pos += size
        return result


conn = Conn()

# experiment with your loop here
...
while True:
    ...
            print("GOT", pickle.loads(data[:item_len]))
    ...
    chunk = conn.recv(32)

Once you see

$ python3.8 demo.py
GOT (0, 'Hello World', 42.0)
GOT (1, 'Hello World', 42.0)
GOT (2, 'Hello World', 42.0)
...
GOT (99, 'Hello World', 42.0)

(come here with more specific questions if you're stuck) you can pretty much 
copy and paste the loop into your client.



More information about the Tutor mailing list