HCLivess
HCLivess

Reputation: 1073

Passing data over sockets using pickle and variable length

this is the code I am currently using. But I would like it to be able to send serialized data using pickle. I have been tinkering with it for a few hours now with no luck. Perhaps if someone here has better networking experience, quick insight would be appreciated so I don't have to rewrite everything, I think it's confusing as it is already.

import select

def send(sdef, data, slen):
    sdef.setblocking(0)

    sdef.sendall(str(len(str(data))).encode("utf-8").zfill(slen))
    sdef.sendall(str(data).encode("utf-8"))


def receive(sdef, slen):
    sdef.setblocking(0)
    ready = select.select([sdef], [], [], 60)
    if ready[0]:
        data = int(sdef.recv(slen))  # receive length
        # print "To receive: "+str(data)
    else:
        raise RuntimeError("Socket timeout")

    chunks = []
    bytes_recd = 0
    while bytes_recd < data:
        ready = select.select([sdef], [], [], 60)
        if ready[0]:
            chunk = sdef.recv(min(data - bytes_recd, 2048))
            if chunk == b'':
                raise RuntimeError("Socket connection broken")
            chunks.append(chunk)
            bytes_recd = bytes_recd + len(chunk)
        else:
             raise RuntimeError("Socket timeout")

    segments = b''.join(chunks).decode("utf-8")
    # print "Received segments: "+str(segments)

    return segments

Simplest implementation:

import select, pickle

def send(sdef, data, slen):
    sdef.setblocking(0)

    sdef.sendall(str(len(str(pickle.dumps(data)))).encode("utf-8").zfill(slen))
    sdef.sendall(str(pickle.dumps(data)).encode("utf-8"))


def receive(sdef, slen):
    sdef.setblocking(0)
    ready = select.select([sdef], [], [], 60)
    if ready[0]:
        data = int(sdef.recv(slen))  # receive length
        # print "To receive: "+str(data)
    else:
        raise RuntimeError("Socket timeout")

    chunks = []
    bytes_recd = 0
    while bytes_recd < data:
        ready = select.select([sdef], [], [], 60)
        if ready[0]:
            chunk = sdef.recv(min(data - bytes_recd, 2048))
            if chunk == b'':
                raise RuntimeError("Socket connection broken")
            chunks.append(chunk)
            bytes_recd = bytes_recd + len(chunk)
        else:
             raise RuntimeError("Socket timeout")

    segments = b''.join(chunks).decode("utf-8")
    # print "Received segments: "+str(segments)

    return segments

and I cannot deserialize "segments" anymore, because it is a string

Upvotes: 0

Views: 290

Answers (1)

HCLivess
HCLivess

Reputation: 1073

This is the way to get it, literaleval should work under all circumstances on serialized data

pickle.loads(ast.literal_eval(segments))

Upvotes: 1

Related Questions