// // Sender Window Buffer // // Idea: // o The explanation assumes inifinite sequence numbers, but can be easily // modified to handle a finite sequence number set. // o The sender window buffer has w slots. Each slot contains a pkt descriptor. // o Since the number of slots w is static, the slot number (index) k can be // determined from the pkt# 'sn': k = sn%w // // o Example (w = 6, lo = 9) // Actual Structure: // k = 0 1 2 3 4 5 // ----------------------------------------------- // | | | | | | | // ----------------------------------------------- // sn = 0 1 2 3 4 5 // 6 7 8 9 10 11 // 12 13 14 15 16 17 // etc. // Logical View (lo = 9): // k = 3 4 5 0 1 2 // ----------------------------------------------- // | | | | | | | // ----------------------------------------------- // sn = 9 10 11 12 13 14 // Usage Patterns: // // o Create a w-slot window buffer: SndWinBuf *swin = new SndWinBuf(w); // o Display the window buffer state: swin->dump(); // o Sender gets ACC x pkt: swin->ackWin(x); swin->advWin(); // Set accept flag for all pkts // with sequence numbers less than x. // o Get the number of accepted pkts: nAccepts = swin->lo; // o Retransmit pkt with seq num sn: swin->incNtries(sn); // o Transmit next pkt: swin->insert(swin->nxtSn()); // typedef struct { // structure of each buffer slot Bool empty; // YES if slot is empty Bool accept; // pkt has been accepted by rcvr? int nTries; // # times pkt was sent } Sbuf; class SndWinBuf { public: int lo; // lowest sn in window (RO) int w; // window size (#pkts) (RO) int n; // #pkts in window (RO) SndWinBuf(int w0); // create new sender window buffer with w0 slots void advWin(void); // advance window until 1st slot has not been ACKed inline void dump(void) { // dump buffer printf (" SndWinBuf: lo = %d, n = %d\n ", lo, n); for (int i=0; i= lo) && (sn0 < (lo+w))) return YES; else return NO; } inline void incNtries(int sn0) { // increment nTries field for pkt with sn sn0 ++(buf[sn0%w].nTries); } private: Sbuf *buf; // w buffer ptrs };