2

I'd like to implement a sliding window mechanism into the following code, looking for any advice on where to start.

Currently the sender keeps sending and collecting its own packets, and I'm not really sure why that is, could someone help me fix that and guide me in the right direction for implementing the protocol?

Thanks

sender.py

import sys
from Queue import Queue
from state import StateMachine
import rdtlib
from rdtlib import rdt_send, udt_send, isACK, iscorrupt, rdt_rcv

# Globals
lastsndpkt = None # Holds last sent packet in case it needs to be retransmitted
nextseqnum = 0
base = 0
sent = 0
retrans = 0

# Set up a queue of packets to send
sendbuf = Queue()
for i in 'ABCDEFGHIJ':
    sendbuf.put(i)

# Handle the sender's 'Wait for call from above' state
def sender_wait_above():
    global lastsndpkt, nextseqnum, sent

    print 'Sender in state WAIT_ABOVE'
    # If we have some data to send, send it using nextseqnum
    if not sendbuf.empty():
        lastsndpkt = rdt_send(sendbuf.get(), nextseqnum)
        sent += 1
        # Advance nextseqnum for next packet that will be sent
        nextseqnum += 1
        return 'WAIT_ACK'     # Wait for the ACK
    else:
        return 'S_END'        # Terminate state machine

# Handle the sender's 'Wait for ACK' state
def sender_wait_ack():
    global lastsndpkt, retrans, base
    print 'Sender in state WAIT_ACK'

    # Wait to receive an ACK packet
    packet = rdt_rcv(timeout=None)

    # TODO: These three error condtions could be collapsed into a single case
    if packet == None:    # Timeout!
        print 'Sender: Timeout, retransmitting', lastsndpkt
        udt_send(lastsndpkt)
        retrans += 1
        return 'WAIT_ACK'

    if iscorrupt(packet):
        print 'Sender: Corrupt ACK, retransmitting', lastsndpkt
        udt_send(lastsndpkt)
        retrans += 1
        return 'WAIT_ACK'

    if not isACK(packet, base):
        print 'Sender: Duplicate ACK, retransmitting', lastsndpkt
        udt_send(lastsndpkt)
        retrans += 1
        return 'WAIT_ACK'

    # Expected ACK is received, advance base of sender window by 1
    if isACK(packet, base):
        base += 1
        return 'WAIT_ABOVE'

    # Default case, keep waiting for an ACK
    return 'WAIT_ACK'


def SenderDone():
    print 'Send buffer empty, exiting'
    print 'Sent: ', sent
    print 'Retransmitted: ', retrans

#
# Set up the state machine
#
def start_sender():
    sender = StateMachine('sender')
    sender.add_state('WAIT_ABOVE', sender_wait_above)
    sender.add_state('WAIT_ACK', sender_wait_ack)
    sender.add_state('S_END', SenderDone, end_state=1)
    sender.set_initial_state('WAIT_ABOVE')
    sender.run()

rdtlib.peer = ('10.0.0.2', 12002)

start_sender()

receiver.py

import sys
from state import StateMachine
import rdtlib
from rdtlib import udt_send, rdt_send, rdt_rcv, deliver_data, make_pkt, extract, iscorrupt, hasSeq, ACK

# Globals
expectedseqnum = 0
sndpkt = make_pkt(type=ACK, seq=expectedseqnum)

# Handle the receiver's 'Wait for call from below' states
#
# There are three cases to handle for each of these:
# 1. Packet is corrupt
# 2. Packet is out-of-sequence
# 3. Packet is OK
def receiver_wait_below():
    global expectedseqnum, sndpkt

    print 'Receiver in state WAIT_BELOW, expecting seqnum', expectedseqnum
    packet = rdt_rcv()

    # We have a good packet with the expected seqnum, so deliver data
    # to app layer and send an acknowledgement
    if (not iscorrupt(packet)) and hasSeq(packet, expectedseqnum):

         # Extract data and pass to application layer
         data = extract(packet)
         deliver_data(data)

         # Prepare an ACK pack for this seqnum
         print 'Receiver: packet OK, sending ACK for', expectedseqnum
         sndpkt = make_pkt(type=ACK, seq=expectedseqnum)

         # Increment seqnum
         expectedseqnum += 1

   else:
        # The packet received is either corrupt or out-of-sequence,
        # send the last ACK packet

        # TODO: print error message that indicates what is wrong
        print 'Receiver: bad packet, sending last ACK'

   # Send the ACK packet to the sender
   udt_send(sndpkt)

   return 'WAIT_BELOW'


def ReceiverDone():
   pass

#
# Set up the state machine
#

def start_receiver():
   receiver = StateMachine('receiver')
   receiver.add_state('WAIT_BELOW', receiver_wait_below)
   receiver.add_state('R_END', ReceiverDone, end_state=1)
   receiver.set_initial_state('WAIT_BELOW')
   receiver.run()

rdtlib.peer = ('10.0.0.1', 12002)
start_receiver()  
coderboy99
  • 103
  • 8

0 Answers0