Selective Repeat ARQ using C Language - BunksAllowed

BunksAllowed is an effort to facilitate Self Learning process through the provision of quality tutorials.

Community

Selective Repeat ARQ using C Language

Share This
Source code of CRC
#ifndef CRCH #define CRCH unsigned short crc_16(unsigned char[100], unsigned short); unsigned short crc_16(unsigned char input[100], unsigned short len) { unsigned short crc = 0xFFFF; unsigned short temp, i, j; unsigned char msg[100]; memcpy(msg, input, len); for (j = 0; j < len; j++) { for (i = 0; i <= 7; i++) { temp = (crc >> 15) ^ (msg[j] >> 7); crc <<= 1; if (temp) { crc ^= 0x1021; } msg[j] <<= 1; } } return crc; } #endif

Source code of UDP Selective Repeat Server
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include "crc.h" int main() { short int n = 0, m = 0, i = 1, correct_recv = 0; int len = 100; int addrlen, Tx_len; unsigned short seq_no, nack_seq_no = 15; unsigned short serv_port = 25000; short sockfd; unsigned short crc, recv_crc; char serv_ip[] = "127.0.0.1"; char mesg[1000]; char Tx_message[100]; char ack[] = "ACK"; char nak[] = "NAK"; unsigned char Tx_maeesage[100]; char *client; int ksd; struct sockaddr_in servaddr, clientaddr; client = (char *) malloc(sizeof(servaddr)); sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { printf("failed"); exit(0); } printf("\n\t socket created.....\n"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; ksd = inet_aton(serv_ip, &servaddr.sin_addr); printf("%d", ksd); servaddr.sin_port = htons(serv_port); bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); while (1) { n = recvfrom(sockfd, mesg, len, 0, (struct sockaddr *) &clientaddr, &addrlen); memcpy(&seq_no, mesg, sizeof(unsigned short)); memcpy(Tx_message, mesg, sizeof(unsigned short)); mesg[n] = '\0'; printf("\n %s \n", mesg); crc = crc_16(mesg, n); printf("\n crc=%x \n", crc); //sleep(5); if (seq_no <= 3) { if (crc == 0) { memcpy(&Tx_message[2], ack, strlen(ack)); correct_recv++; printf("\n\t\t\t ack for %d\n", seq_no); } else { memcpy(&Tx_message[2], nak, strlen(nak)); printf("\n\t\t\t nack for %d\n", seq_no); //i=correct_recv; } Tx_message[2 + strlen(ack)] = '\0'; Tx_len = sizeof(seq_no) + strlen(ack); m = sendto(sockfd, Tx_message, Tx_len, 0, (struct sockaddr *) &clientaddr, sizeof(clientaddr)); if (m!=-1) printf("\n\t send success.....\n"); else printf("\n\t send failure.....\n"); } if (correct_recv == 3) break; } close(sockfd); }

Source code of UDP Selective Repeat Client
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include "crc.h" static void sig_io(int); enum { false, true } flag; int sockfd, returnvalue, len = 100, n, i = 1, j = 1, k = 1; unsigned short seq_no = 1, seq_no_ret, crc, shift_crc, correct_recv = 0; unsigned short error_seq_no = 15; unsigned int addrlen; unsigned short serv_port = 25000; char serv_ip[] = "127.0.0.1"; char *text[3] = { "abcde", "fghij", "klmno" }; unsigned char Tx_message[100]; unsigned char Tx_message_copy[100]; char rtext[100]; int Tx_len; struct sockaddr_in servaddr; int main() { int val; addrlen = sizeof(servaddr); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(serv_port); inet_aton(serv_ip, &servaddr.sin_addr); sockfd = socket(PF_INET, SOCK_DGRAM, 0); val = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, val | O_NONBLOCK | O_ASYNC); fcntl(sockfd, F_SETOWN, getpid()); signal(SIGIO, sig_io); flag = false; while (1) { if (seq_no <= 3 && (flag == false)) { printf(" seq_no=%d\n", seq_no); memcpy(Tx_message, &seq_no, sizeof(seq_no)); memcpy(&Tx_message[2], text[seq_no - 1], 5); memcpy(Tx_message_copy, Tx_message, 7); crc = crc_16(Tx_message_copy, sizeof(unsigned short) + strlen(text[seq_no - 1])); shift_crc = crc; shift_crc = (shift_crc << 8) ^ (0x0000); crc = (crc >> 8) ^ (0x0000); crc = (shift_crc) ^ (crc); if (seq_no == 2 && j == 1) { crc = 0x5555; j++; } memcpy(&Tx_message[7], &crc, sizeof(unsigned short)); Tx_message[9] = '\0'; Tx_len = sizeof(seq_no) + strlen(text[seq_no - 1]) + sizeof(crc); returnvalue = sendto(sockfd, Tx_message, Tx_len, 0, (struct sockaddr *) &servaddr, sizeof(servaddr)); seq_no++; /* if(returnvalue!=-1) { printf("\n\t message %d sent successfully.....\n",i); i++; } else printf("\n\t message %d sent failure.....\n",i); */ } else if (flag == true) { memcpy(Tx_message, &error_seq_no, sizeof(error_seq_no)); memcpy(&Tx_message[2], text[error_seq_no - 1], 5); memcpy(Tx_message_copy, Tx_message, 7); crc = crc_16(Tx_message_copy, sizeof(unsigned short) + strlen(text[error_seq_no - 1])); shift_crc = crc; shift_crc = (shift_crc << 8) ^ (0x0000); crc = (crc >> 8) ^ (0x0000); crc = (shift_crc) ^ (crc); memcpy(&Tx_message[7], &crc, sizeof(unsigned short)); Tx_message[9] = '\0'; Tx_len = sizeof(error_seq_no) + strlen(text[error_seq_no - 1]) + sizeof(crc); returnvalue = sendto(sockfd, Tx_message, Tx_len, 0, (struct sockaddr *) &servaddr, sizeof(servaddr)); flag = false; } else { if (correct_recv == 3) break; else continue; } } close(sockfd); return 0; } static void sig_io(int signo) { n = recvfrom(sockfd, rtext, len, 0, (struct sockaddr *) &servaddr, &addrlen); if (n != -1) { rtext[n] = '\0'; memcpy(&seq_no_ret, rtext, sizeof(unsigned short)); if (memcmp(&rtext[2], "ACK", 3) == 0) { printf("\n ACK for %d\n", seq_no_ret); correct_recv++; flag = false; //sleep(3); } else { error_seq_no = seq_no_ret; flag = true; printf("\n NAK for %d\n", error_seq_no); //sleep(3); } } }

Happy Exploring!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.