Я бы хотел внедрить механизм скользящего окна в следующий код, ища какие-либо советы о том, с чего начать.
В настоящее время отправитель продолжает отправлять и собирать свои собственные пакеты, а я на самом деле не являюсь конечно, почему, может кто-нибудь помочь мне исправить это и направить меня в правильном направлении для реализации протокола?
Спасибо
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()
receive.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()