int clientSlidingWindow( UdpSocket &sock, const int max, int message[], int windowSize ) { cerr << "Sliding-window test:" << endl; int lar = -1; // last acknowledgment received int seq = 0; // current seq # int retransmits = 0; if(sock.pollRecvFrom() > 0) { // check for any old acks sock.recvFrom( ( char * ) message, MSGSIZE ); // clean out the socket } vector<int> window(windowSize); for(int i = 0; i < windowSize; i++) { //init window window[i] = -1; } Timer t; while( seq < max) { while(seq - lar <= windowSize && seq < max) { // while seq is within window message[0] = seq; // append seq to message sock.sendTo((char*) message, MSGSIZE); // send message seq++; // increment seq } long lap; t.start(); // timer start while ((lap = t.lap()) < 1500) { if(sock.pollRecvFrom() > 0) { // while not timed out getAck(lar, sock); // check for an ack break; } } if (lap >=1500) { // if no ack seq = lar+1; // reset sequence # retransmits++; } } return retransmits; }
int clientStopWait( UdpSocket &sock, const int max, int message[] ) { cerr << "client: stop-and-wait test:" << endl; int retransmits = 0; // transfer message[] max times for ( int i = 0; i < max; ) { message[0] = i; sock.sendTo( ( char * )message, MSGSIZE ); timer.start(); // If the client cannot receive an ack immediately, start a timer while (sock.pollRecvFrom( ) <= 0) { // If a timeout has happened, client must resend the same message if ( timer.lap() >= TIMEOUT ) { retransmits++; break; } } // Did not retransmit; if ( timer.lap() < TIMEOUT ) { // Receive ACK from server sock.recvFrom( ( char * ) message, MSGSIZE ); i++; } } return retransmits; }
// Test 1: client unreliable message send ------------------------------------- void clientUnreliable( UdpSocket &sock, const int max, int message[] ) { cerr << "client: unreliable test:" << endl; // transfer message[] max times for ( int i = 0; i < max; i++ ) { message[0] = i; // message[0] has a sequence # sock.sendTo( ( char * )message, MSGSIZE ); // udp message send cerr << "message = " << message[0] << endl; } }
int clientStopWait( UdpSocket &sock, const int max, int message[] ) { cerr << "Stop-and-wait test:" << endl; Timer t; int retransmits = 0; for ( int i = 0; i < max; i++ ) { // transfer message[] max times message[0] = i; // message[0] has a sequence # sock.sendTo((char*) message, MSGSIZE); // send message t.start(); // start timer long lap; while ((lap = t.lap()) < 1500) { if(sock.pollRecvFrom() > 0) { // if ack received before timer ends sock.recvFrom((char*)message, MSGSIZE); break; } } if (lap >= 1500) { // timeout, so retransmit i--; retransmits++; cerr << retransmits << endl; } } return retransmits; }
int clientSlidingWindow(UdpSocket &sock, const int max, int message[], int windowSize) { cerr << "Client sliding window test:" << endl; int retransmits = 0; // Tracks the number of retransmitted messages int ack; // Hold the acknowledgment from the server int base = 0; // Tracks the client's message seq# int sequence = 0; // The sequence # counter // Send and receive messages while (sequence < max || base < max) { // Open sliding window for use if (base + windowSize > sequence && sequence < max) { message[0] = sequence; sock.sendTo((char *)message, MSGSIZE); // Check if ack arrived if (sock.pollRecvFrom() > 0) { sock.recvFrom((char *)message, MSGSIZE); ack = message[0]; if (ack == base) { base++; } } // Increment sequence and shrink the window sequence++; } // Sliding window is full, start timer else { timer.start(); // Looks for ACKs and timeouts while (true) { // Found ack if (sock.pollRecvFrom() > 0) { sock.recvFrom((char *)message, MSGSIZE); ack = message[0]; // Move base up if the server is ahead in messages if (ack >= base) { base = ack + 1; } // Resend the server the message that it needs else { message[0] = ack; sock.sendTo((char *)message, MSGSIZE); retransmits++; } break; } // Timed Out else if (timer.lap() > TIMEOUT) { // Resend message to server message[0] = base; sock.sendTo((char *)message, MSGSIZE); retransmits++; break; } } } } return retransmits; }
int clientSlidingWindow(UdpSocket &sock, const int max, int message[], const int windowSize) { int retransmits = 0; int ack; int ackSeq = 0; // expected ack to receive // transfer all max messages for (int msgNum = 0; msgNum < max && ackSeq < max;) { int numOfUnAck = msgNum - ackSeq; // sliding window has space if (numOfUnack < windowSize) { // set-up message and send message[0] = msgNum; sock.sendTo((char *)message, MSGSIZE); // check for acknowledgement if (sock.pollRecvFrom() != 0) { sock.recvFrom((char *)&ack, sizeof(ack)); if (ack == ackSeq) ackSeq++; } msgNum++; // sliding window is full } else { Timer t; t.start(); bool ackReceived = false; // wait for acknowledgement within TIMEOUT while (t.lap() < TIMEOUT) { // check for acknowledgement if (sock.pollRecvFrom() != 0) { ackReceived = true; sock.recvFrom((char *)&ack, sizeof(ack)); // every message up to ack has been received if (ack >= ackSeq) ackSeq = ack + 1; else { // message # ack never received, resend message[0] = ack; sock.sendTo((char *)message, MSGSIZE); retransmits++; } break; } } // resend minimum unacknowledged sequence number on timeout if (!ackReceived) { message[0] = ackSeq; sock.sendTo((char *)message, MSGSIZE); retransmits++; } } } return retransmits; }