如何在这些程序中添加滑动窗口机制?

2024-05-03 08:28:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在下面的代码中实现一个滑动窗口机制,寻找关于从哪里开始的建议

目前,发送方一直在发送和收集自己的数据包,我不确定这是为什么,有人能帮我解决这个问题,并指导我朝着正确的方向实现协议吗

谢谢

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()  

Tags: thetoimportsendforreturnpacketsender