├── Makefile ├── packet.h ├── README.md ├── go-back-n-receiver.cpp ├── stop-wait-receiver.cpp ├── noisy_channel.cpp ├── stop-wait-sender.cpp ├── selective-repeat-receiver.cpp ├── go-back-n-sender.cpp └── selective-repeat-sender.cpp /Makefile: -------------------------------------------------------------------------------- 1 | all: noisy_channel stop-wait-receiver stop-wait-sender go-back-n-sender go-back-n-receiver selective-repeat-sender selective-repeat-receiver 2 | 3 | clean: 4 | rm -f channel_l_in channel_r_in channel_l_out channel_r_out 5 | rm -f noisy_channel stop-wait-receiver stop-wait-sender go-back-n-sender go-back-n-receiver selective-repeat-sender selective-repeat-receiver 6 | -------------------------------------------------------------------------------- /packet.h: -------------------------------------------------------------------------------- 1 | #ifndef packet_h 2 | #define packet_h 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define DEBUG printf("%d\n", __LINE__) 13 | 14 | struct Packet { 15 | int seq_no; 16 | bool valid; 17 | }; 18 | 19 | const char * clin = "channel_l_in"; 20 | const char * clout = "channel_l_out"; 21 | const char * crin = "channel_r_in"; 22 | const char * crout = "channel_r_out"; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Network Protocol Simulations 2 | ============================ 3 | 4 | Simulations of Stop-and-Wait, Go-Back-N, Selective-Repeat protocols. 5 | These were made for Computer Networks Lab Assignment at IIT Roorkee. 6 | 7 | Usage 8 | ----- 9 | 10 | Compile everything using a `make` in the directory. 11 | 12 | In order to simulate any one of the protocols, first start up the `noisy-channel` in one terminal, switch to another terminal and start up the `sender`, and the corresponding `receiver` in yet another terminal. 13 | 14 | License 15 | ------- 16 | 17 | Licensed under [MIT License](http://jay.mit-license.org/2015) 18 | -------------------------------------------------------------------------------- /go-back-n-receiver.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int current; 4 | int read_end, write_end; 5 | 6 | void send_ack(int packet_no) { 7 | Packet p; 8 | p.seq_no = packet_no; 9 | p.valid = true; 10 | 11 | write(write_end, &p, sizeof(p)); 12 | 13 | printf("Sent acknowledgement %d\n", current); 14 | } 15 | 16 | int main() { 17 | write_end = open(crin, O_WRONLY); 18 | read_end = open(crout, O_RDONLY); 19 | 20 | current = 0; 21 | 22 | for (;;) { 23 | Packet p; 24 | 25 | while ( true ) { 26 | int ret = read(read_end, &p, sizeof(p)); 27 | if ( ret == 0 ) { 28 | break; 29 | } else if ( ret < 0 ) { 30 | perror("read"); 31 | exit(-1); 32 | } 33 | if ( p.seq_no == current && p.valid == true ) { 34 | printf("Received packet %d successfully.\n", p.seq_no); 35 | current += 1; 36 | send_ack(current); 37 | break; 38 | } else { 39 | printf("Received packet %d. Valid = %d.\n", p.seq_no, p.valid); 40 | send_ack(current); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /stop-wait-receiver.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int current; 4 | int read_end, write_end; 5 | 6 | void send_ack(int packet_no) { 7 | Packet p; 8 | p.seq_no = packet_no; 9 | p.valid = true; 10 | 11 | write(write_end, &p, sizeof(p)); 12 | 13 | printf("Sent acknowledgement %d\n", current); 14 | } 15 | 16 | int main() { 17 | write_end = open(crin, O_WRONLY); 18 | read_end = open(crout, O_RDONLY); 19 | 20 | current = 0; 21 | 22 | for (;;) { 23 | Packet p; 24 | 25 | while ( true ) { 26 | int ret = read(read_end, &p, sizeof(p)); 27 | if ( ret == 0 ) { 28 | break; 29 | } else if ( ret < 0 ) { 30 | perror("read"); 31 | exit(-1); 32 | } 33 | if ( p.seq_no == current && p.valid == true ) { 34 | printf("Received packet %d successfully.\n", p.seq_no); 35 | current += 1; 36 | send_ack(current); 37 | break; 38 | } else { 39 | printf("Received packet %d. Valid = %d.\n", p.seq_no, p.valid); 40 | send_ack(current); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /noisy_channel.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int main() { 4 | int drop_prob; 5 | 6 | printf("Drop Probability? "); 7 | scanf("%d", &drop_prob); 8 | 9 | int in, out; 10 | char *type; 11 | mkfifo(clin, 0777); 12 | mkfifo(crout, 0777); 13 | mkfifo(clout, 0777); 14 | mkfifo(crin, 0777); 15 | 16 | if ( fork() ) { 17 | in = open(clin, O_RDONLY); 18 | out = open(crout, O_WRONLY); 19 | type = "data"; 20 | } else { 21 | in = open(crin, O_RDONLY); 22 | out = open(clout, O_WRONLY); 23 | type = "ACK"; 24 | } 25 | 26 | Packet p; 27 | 28 | while ( true ) { 29 | int ret = read(in, &p, sizeof(p)); 30 | if ( ret == 0 ) { 31 | break; 32 | } else if ( ret < 0 ) { 33 | perror(type); 34 | exit(-1); 35 | } 36 | 37 | printf("Received %s packet. Seq no = %d.\n", type, p.seq_no); 38 | 39 | if ( random() % 100 < drop_prob ) { 40 | p.valid = false; 41 | printf("Packet %d was corrupted.\n", p.seq_no); 42 | } 43 | 44 | write(out, &p, sizeof(p)); 45 | 46 | printf("Transmitted %s packet. Seq no = %d.\n", type, p.seq_no); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /stop-wait-sender.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int current; 4 | bool outstanding; 5 | int read_end, write_end; 6 | 7 | void send_packet(int packet_no) { 8 | Packet p; 9 | p.seq_no = packet_no; 10 | p.valid = true; 11 | 12 | write(write_end, &p, sizeof(p)); 13 | 14 | printf("Sent packet %d\n", current); 15 | } 16 | 17 | static void sighandler(int sig) { 18 | if ( outstanding ) { 19 | printf("Time-out. Resending packet.\n"); 20 | send_packet(current); 21 | alarm(1); 22 | } 23 | } 24 | 25 | int main() { 26 | int total_packets; 27 | printf("Totally, how many packets to send? "); 28 | scanf("%d", &total_packets); 29 | 30 | write_end = open(clin, O_WRONLY); 31 | read_end = open(clout, O_RDONLY); 32 | 33 | signal(SIGALRM, sighandler); 34 | 35 | current = 0; 36 | 37 | for ( int i = 0 ; i < total_packets ; i++ ) { 38 | alarm(1); 39 | Packet ack; 40 | 41 | send_packet(current); 42 | outstanding = true; 43 | 44 | while ( read(read_end, &ack, sizeof(ack)) ) { 45 | if ( ack.seq_no == current+1 && ack.valid == true ) { 46 | outstanding = false; 47 | break; 48 | } 49 | } 50 | 51 | current += 1; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /selective-repeat-receiver.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int current; 4 | int read_end, write_end; 5 | int window = 4; 6 | 7 | bool received[10000]; 8 | 9 | void send_ack(int packet_no) { 10 | Packet p; 11 | p.seq_no = packet_no; 12 | p.valid = true; 13 | 14 | write(write_end, &p, sizeof(p)); 15 | 16 | printf("Sent acknowledgement %d\n", current); 17 | } 18 | 19 | int main() { 20 | write_end = open(crin, O_WRONLY); 21 | read_end = open(crout, O_RDONLY); 22 | 23 | current = 0; 24 | 25 | for (;;) { 26 | Packet p; 27 | 28 | while ( true ) { 29 | int ret = read(read_end, &p, sizeof(p)); 30 | if ( ret == 0 ) { 31 | break; 32 | } else if ( ret < 0 ) { 33 | perror("read"); 34 | exit(-1); 35 | } 36 | printf("Received packet %d. Valid = %d.\n", p.seq_no, p.valid); 37 | if ( p.valid && p.seq_no >= current && p.seq_no < current + window ) { 38 | printf("Received packet %d successfully.\n", p.seq_no); 39 | received[p.seq_no] = true; 40 | send_ack(p.seq_no); 41 | while ( received[current] ) { 42 | current += 1; 43 | printf("Slid window to %d.\n", current); 44 | } 45 | } else { 46 | send_ack(current); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /go-back-n-sender.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int current; 4 | bool outstanding; 5 | int read_end, write_end; 6 | int window = 4; 7 | int total_packets; 8 | 9 | void send_packet(int packet_no) { 10 | Packet p; 11 | p.seq_no = packet_no; 12 | p.valid = true; 13 | 14 | write(write_end, &p, sizeof(p)); 15 | 16 | printf("Sent packet %d\n", packet_no); 17 | } 18 | 19 | void send_set() { 20 | for ( int i = 0 ; i < window ; i++ ) { 21 | if ( current + i < total_packets ) { 22 | send_packet(current + i); 23 | outstanding = true; 24 | } 25 | } 26 | } 27 | 28 | static void sighandler(int sig) { 29 | if ( outstanding && current < total_packets ) { 30 | printf("Time-out. Resending set.\n"); 31 | send_set(); 32 | alarm(1); 33 | } 34 | } 35 | 36 | int main() { 37 | printf("Totally, how many packets to send? "); 38 | scanf("%d", &total_packets); 39 | 40 | write_end = open(clin, O_WRONLY); 41 | read_end = open(clout, O_RDONLY); 42 | 43 | signal(SIGALRM, sighandler); 44 | 45 | current = 0; 46 | 47 | for ( ;; ) { 48 | alarm(1); 49 | Packet ack; 50 | 51 | send_set(); 52 | 53 | while ( read(read_end, &ack, sizeof(ack)) ) { 54 | if ( (ack.seq_no >= current + window || ack.seq_no >= total_packets) && ack.valid == true ) { 55 | outstanding = false; 56 | } 57 | if ( ack.seq_no > current && ack.valid == true ) { 58 | current = ack.seq_no; 59 | printf("Slid window to %d.\n", current); 60 | } 61 | } 62 | 63 | if ( current >= total_packets ) { 64 | break; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /selective-repeat-sender.cpp: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | 3 | int current; 4 | bool outstanding; 5 | int read_end, write_end; 6 | int window = 4; 7 | int total_packets; 8 | 9 | bool acknowledged[10000]; 10 | 11 | void send_packet(int packet_no) { 12 | Packet p; 13 | p.seq_no = packet_no; 14 | p.valid = true; 15 | 16 | write(write_end, &p, sizeof(p)); 17 | 18 | printf("Sent packet %d\n", packet_no); 19 | } 20 | 21 | void send_set() { 22 | for ( int i = 0 ; i < window ; i++ ) { 23 | if ( !acknowledged[current + i] ) { 24 | send_packet(current + i); 25 | outstanding = true; 26 | } 27 | } 28 | } 29 | 30 | static void sighandler(int sig) { 31 | if ( outstanding && current < total_packets ) { 32 | printf("Time-out. Resending set.\n"); 33 | send_set(); 34 | alarm(1); 35 | } 36 | if ( current >= total_packets ) { 37 | exit(0); 38 | } 39 | } 40 | 41 | int main() { 42 | printf("Totally, how many packets to send? "); 43 | scanf("%d", &total_packets); 44 | 45 | write_end = open(clin, O_WRONLY); 46 | read_end = open(clout, O_RDONLY); 47 | 48 | signal(SIGALRM, sighandler); 49 | 50 | current = 0; 51 | 52 | for ( ;; ) { 53 | alarm(1); 54 | Packet ack; 55 | 56 | send_set(); 57 | 58 | while ( read(read_end, &ack, sizeof(ack)) ) { 59 | if ( (ack.seq_no >= current + window || ack.seq_no >= total_packets) && ack.valid == true ) { 60 | outstanding = false; 61 | } 62 | if ( ack.seq_no >= current && ack.valid == true ) { 63 | printf("Received ack for %d.\n", ack.seq_no); 64 | acknowledged[ack.seq_no] = true; 65 | 66 | while ( acknowledged[current] ) { 67 | current += 1; 68 | printf("Slid window to %d.\n", current); 69 | } 70 | } 71 | } 72 | 73 | if ( current >= total_packets ) { 74 | break; 75 | } 76 | } 77 | } 78 | --------------------------------------------------------------------------------