0% found this document useful (0 votes)
20 views

Cnlab 5 Q 4

Uploaded by

cs22b1047
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views

Cnlab 5 Q 4

Uploaded by

cs22b1047
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

KSHITIJ SINGH CN_LAB5 CS22B1047

Q4:

SENDER:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>

#define PORT 8080


#define TIMEOUT 2 // Timeout in seconds

int window_size;
int total_packets;
int *sent_packets; // Track if packets are sent

// Function to simulate packet loss with a 20% chance


int simulate_packet_loss() {
return rand() % 5 == 0;
}

// Function to send a packet


void send_packet(int sock, int seq_num) {
printf("Sending packet %d...\n", seq_num);
send(sock, &seq_num, sizeof(seq_num), 0);
sent_packets[seq_num - 1] = 1; // Mark packet as sent
}

// Function to send packets within the window size


void send_window(int sock, int base, int next_seq_num) {
for (int i = base; i < base + window_size && i <= total_packets; i++) {
if (!sent_packets[i - 1]) {
send_packet(sock, i);
}
}
}

void selective_repeat(int sock) {


int base = 1;
int ack, next_seq_num = 1;
fd_set fds;
struct timeval tv;

while (base <= total_packets) {


send_window(sock, base, next_seq_num);

// Wait for acknowledgment


FD_ZERO(&fds);
FD_SET(sock, &fds);
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;

int retval = select(sock + 1, &fds, NULL, NULL, &tv);


if (retval == -1) {
perror("select() error");
return;
} else if (retval) {
// Receive acknowledgment
recv(sock, &ack, sizeof(ack), 0);
printf("Received ACK for packet %d.\n", ack);
sent_packets[ack - 1] = 2; // Mark packet as acknowledged

// Slide the window


while (sent_packets[base - 1] == 2 && base <= total_packets) {
base++;
}
} else {
// Timeout, retransmit unacknowledged packets
printf("Timeout! Retransmitting unacknowledged packets...\n");
send_window(sock, base, next_seq_num);
}
}

printf("All packets sent successfully.\n");


}

int main() {
int sock = 0;
struct sockaddr_in serv_addr;

// Create socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

// Convert IPv4 address from text to binary form


if (inet_pton(AF_INET, "172.16.14.42", &serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}

// Connect to the receiver


if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}

// Get total number of packets and window size from user


printf("Enter total number of packets to send: ");
scanf("%d", &total_packets);
printf("Enter window size: ");
scanf("%d", &window_size);

sent_packets = (int *)calloc(total_packets, sizeof(int));

// Start the Selective Repeat ARQ process


selective_repeat(sock);

free(sent_packets);
close(sock);
return 0;
}

RECIEVER:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>

#define PORT 8080


int total_packets;
int *received_packets; // Track received packets

// Function to simulate packet loss with a 20% chance


int simulate_packet_loss() {
return rand() % 5 == 0;
}

// Function to handle packet reception


void receive_packet(int new_socket, int seq_num) {
// Simulate packet loss or corruption
if (simulate_packet_loss()) {
printf("Packet %d lost or corrupted. No ACK sent\n", seq_num);
return;
}

if (!received_packets[seq_num - 1]) {
printf("Packet %d received successfully.\n", seq_num);
received_packets[seq_num - 1] = 1; // Mark packet as received
}

// Send ACK for the received packet


send(new_socket, &seq_num, sizeof(seq_num), 0);
}

int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
int seq_num;

srand(time(0)); // Seed for random loss simulation

// Create socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}

// Forcefully attaching socket to the port 8080


if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,
sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}

address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);

// Bind the socket


if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}

// Start listening for incoming connections


if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}

printf("Waiting for connection...\n");

if ((new_socket = accept(server_fd, (struct sockaddr *)&address,


(socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}

printf("Connected to sender.\n");

printf("Enter total number of packets to receive: ");


scanf("%d", &total_packets);

received_packets = (int *)calloc(total_packets, sizeof(int));

while (1) {
int valread = recv(new_socket, &seq_num, sizeof(seq_num), 0);
if (valread <= 0) break;

// Receive the packet and handle ACK


receive_packet(new_socket, seq_num);
}

free(received_packets);
close(new_socket);
close(server_fd);
return 0;
}

OUTPUT:

You might also like