This is an infrastructure program for you to extend to real ARQ program. There are four files: sender.c, receiver.c, sli_sender.c and sli_receiver.c.
You can build your stop and wait ARQ on sender.c and receiver.c, and build the other two schemes on sli_sender.c and sli_receiver.c.
I use UDP socket. In the sender.c, the sender simply sends a packet to the receiver and waits for the response (ACK and NAK).
In the receiver.c, when the receiver receives a packet, it sends a response back.
Obviously, the operations works the fine for stop and wait scheme, but not ideal for the other two. Because the sender should keep sending packets while receiving ACKs. Actually, we should use multithread. But I don't want to make the program too complicated. Thus, I create too sockets. One is for sending, and the other is for receiving. I use select method, i.e., each time after the sender sends a packet, the program will check whether there is a packet which has arrived, then decide whether to receive or send another packet. I made 100 times' iteration and it works fine. You can modify it according to the requirement.
fd_set readfds; FD_ZERO(&readfds); FD_SET(sockfd2, &readfds); tv.tv_sec = 0; tv.tv_usec = 1; // don't care about writefds and exceptfds: if (select(sockfd2+1, &readfds, NULL, NULL, &tv) == -1) { perror("select"); exit(1); } if (FD_ISSET(sockfd2, &readfds)){ /* plan to receive ACK or NAK */ if ((numbytes=recvfrom(sockfd2,buf, 10, 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); }.....}
We work on Linux System.
Compile: gcc -o sender.out sender.c
run: ./sender.out IPaddr
This is server/client mode. Please run receiver.out first.
The program is as follows. The input parameters are data and data length. The output is CRC checksum.
/*** CRC-ITU or old name CRC-CCITT***/ word calcrc(char* ptr, int count) { word crc, i; crc = 0; while (--count >= 0) { crc = crc ^ (word)*ptr++ << 8; for (i = 0; i < 8; ++i) if (crc & 0x8000) crc = crc << 1 ^ 0x1021; else crc = crc << 1; } return (crc & 0xFFFF); }
The integrity check is as follows.
/* crc integrity check of received msg */ crc = calcrc(buf, numbytes-2); mcrc = ((buf[numbytes - 1] & 0xff)<< 8); mcrc |= (buf[numbytes - 2] & 0xff); strncpy(rsp, buf, 7); rsp[7]='\0'; if(crc == mcrc) { printf("The returned msg is \"%s\", and the sequence number is %d\n", rsp,buf[numbytes - 3]); } else{ printf("This is a packet with error\n"); }
The timer is to let the program sleep for some time. We can adjust the time.
/* stop and wait ARQ should use this, compute the round trip time, and set the timer as three round trip time.*/ void us_timer () { struct timeval tv_delay; tv_delay.tv_sec = 1;//seconds tv_delay.tv_usec = 10;//microseconds,not as accurate as it should be:) select (0, (void *) 0, (void *) 0, (void *) 0, &tv_delay); }
We use following method to measure the delay.
double timeval2double(struct timeval *tp); double timeval2double(struct timeval *tp) { return (double)tp->tv_sec + (double)tp->tv_usec/1000000.0; } ... /* This is just a demo to show how timer works, you should comment*/ gettimeofday(¤t_time, &tzp); t1 = timeval2double(¤t_time);//get current time us_timer();//The timer gettimeofday(¤t_time, &tzp); t2 = timeval2double(¤t_time); printf("\nThe time difference is %f\n", t2-t1); /* end */
Please refer to arq.tex for detailed explanation.
I plan to do like this:
Please note:
I produce this rand.txt with MATLAB with commands: rand(10000,1);save rand.txt -ASCII
The procedure is as follows:
FILE *fp; float toss; int numbytes, i, error_or_not=-1; if((fp=fopen("rand.txt", "rb"))==NULL){ printf("can't open file\n"); exit(0); } for (i=0;i<8*(DATALEN+2);i++) { fscanf(fp,"%e", &toss); if ( toss <BIT_ERROR_RATE)error_or_not=1; } printf("The result is %d, if it is posive, append the error, else, simply send the packet\n", error_or_not);
Please don't make the program too complicated. Normally to say, the receiver doesn't need timer or sliding window. The sender controls everything.
Go back N and SR ARQ don't need timer to decide the retransmission. They retransmit because the sliding window is full.
We may set a delay before every transmission because the transmission speed is too fast and it is not convenient for us to control and analyze.
Good luck!