Question

Using two different computers, I have to implement sender and receiver algorithms to send and receive frames. I'm a strong programmer, but relatively new to network programming and python. The algorithms are below.

Sender-site algorithm:

while(true)
{
    WaitForEvent();
    if(Event(RequestToSend))
    {
        GetData();
        MakeFrame();
        SendFrame();
    }

Receiver-site algorithm:

while(true)
{ 
    WaitForEvent();
    if(Event(ArrivalNotification))
    {
        ReceiveFrame();
        ExtractData();
        DeliverData();
    }

I have to implement these algorithms on two separate computers, one as a sender and the other as a receiver. I have no idea where to start or look for examples. I've done some research with little luck. If someone can supply example code or a good article on implementing this, that would be lots of help.

Was it helpful?

Solution

I find myself using Python's Socket Server examples. This will get you going on the SendFrame(), ReceiveFrame(), and DeliverData() routines.

The MakeFrame() and ExtractData(), will vary widely based on how much data you're needing to send back and forth. I will try to dig up some good examples I have used in the past.

If you're looking for a 1 stop solution, I would suggest looking into Twisted. There is a definite learning curve to it, but it might be worth it to you. Note that if you're wanting to package the Python code into an exe using pyInstaller or py2exe, Twisted may give you trouble based on a number of threads I have read.

So after looking back through my notes, the framing aspect was a sore subject for me as I could not find any good examples to help. I instead wrote one from scratch and have (and still am) tweaking it.

As you read up on socket programming you will surely see that just because you send all the data (socket.sendall()) does not mean that you will receive it all after the first socket.recv(). This adds some complexity to the message framing question. Due to lack of examples on the web, below I have a stripped down version of what I am using right now in several processes.

Update
So after further testing the under heavy / bursting I moved away from the regex and process the stream character by character which has greatly improved its performance.

SendFrame(), ReceiveFrame(), ExtractData(), DeliverData() Examples:

MESSAGE_FRAME_START = '@'
MESSAGE_FRAME_END = '#'

def process_raw_socket_message_stream(raw_message_stream):
    message_list = []
    cmd = ''
    last_footer_idx = message_string.rfind(MESSAGE_FRAME_END)
    cmd_str_len = len(message_string)
    byte_cnt = 0
    while (byte_cnt <= last_footer_idx):
        cmd_chr = message_string[byte_cnt]
        cmd += cmd_chr
        if cmd_chr == MESSAGE_FRAME_START:
            cmd = MESSAGE_FRAME_START
        elif cmd_chr == MESSAGE_FRAME_END:
            message_list.append(cmd)

        byte_cnt += 1

    # Remove the parsed data
    if last_footer_idx > 0:
        message_string = message_string[last_footer_idx+1:]

    return message_list, message_string

def add_message_frames(unframed_message):
    return MESSAGE_FRAME_START + unframed_message + MESSAGE_FRAME_END

def remove_message_frames(framed_message):
    clean_message = framed_message.lstrip(MESSAGE_FRAME_START)
    clean_message = clean_message.rstrip(MESSAGE_FRAME_END)
    return clean_message

def process_messsage(clean_message):
    # Do what needs to be done
    pass

def send_data(mysocket, payload):
    framed_payload = add_message_frames(payload)
    mysocket.sendall(framed_payload)

def receive_data(mysocket, byte_size=1024):
    data = ''
    while(1):
        try: # Wait for data
            data += mysocket.recv(byte_size)
            if(data != '') and (data != None):
                # Decode all messsages
                message_list, remaining_data = process_raw_socket_message_stream(data)

                # Process all of the messages
                for messsage in message_list:
                    process_messsage(remove_message_frames(message))

                # Store the remaining data
                data = remaining_data
        except:
            print "Unexpected Error"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top