Network Lab

Implementation of Stop-and-Wait ARQ Protocol Using UDP

To implement the Stop-and-Wait Automatic Repeat reQuest (ARQ) protocol using UDP socket programming in C to ensure reliable data transmission.


Algorithms

Client

Step 1: Create Socket

  • Create a UDP socket using socket(AF_INET, SOCK_DGRAM, 0).
  • If socket creation fails, terminate the program.

Step 2: Define Server Address

  • Set the address family to AF_INET.
  • Set the port number to 5555.
  • Set the IP address to 127.0.0.1.

Step 3: Set Timeout

  • Set a receive timeout using setsockopt() to handle lost acknowledgements.

Step 4: Send Data Packet

  • Initialize sequence number to 0.
  • Send a data packet with the current sequence number using sendto().

Step 5: Wait for Acknowledgement

  • Wait for ACK from the server using recvfrom().
  • If timeout occurs, resend the same packet.
  • If correct ACK is received, toggle the sequence number.

Step 6: Repeat Transmission

  • Repeat the process until all packets are sent.

Step 7: Close Socket

  • Close the client socket.

Server

Step 1: Create Socket

  • Create a UDP socket using socket(AF_INET, SOCK_DGRAM, 0).
  • If socket creation fails, terminate the program.

Step 2: Define Server Address

  • Set the address family to AF_INET.
  • Set the port number to 5555.
  • Set the IP address to 127.0.0.1.

Step 3: Bind Socket

  • Bind the socket to the specified IP address and port using bind().

Step 4: Receive Data Packet

  • Receive a data packet from the client using recvfrom().
  • Extract the sequence number.

Step 5: Check Sequence Number

  • If the received sequence number matches the expected one, accept the packet.
  • Otherwise, identify it as a duplicate packet.

Step 6: Send Acknowledgement

  • Send an ACK for the received sequence number using sendto().
  • (ACK loss may be simulated.)

Step 7: Repeat Process

  • Continue receiving packets and sending acknowledgements.

Programs

Client

#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/time.h> #include <unistd.h> #define TIMEOUT_VALUE 5 #define TOTAL_PACKETS 6 int main() { char *ip = "127.0.0.1"; int port = 5555; int sockfd; struct sockaddr_in addr; char buffer[1024]; socklen_t addr_size; int seq = 0; // 1-bit sequence number int sent_packets = 0; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket error"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(ip); struct timeval timeout; timeout.tv_sec = TIMEOUT_VALUE; timeout.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); while (sent_packets < TOTAL_PACKETS) { memset(buffer, 0, sizeof(buffer)); sprintf(buffer, "DATA:%d", seq); printf("[CLIENT] Sending DATA seq=%d\n", seq); sendto(sockfd, buffer, strlen(buffer) + 1, 0, (struct sockaddr *)&addr, sizeof(addr)); addr_size = sizeof(addr); int rec = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&addr, &addr_size); if (rec < 0) { printf("[CLIENT] Timeout → Resending seq=%d\n", seq); } else { int ack; sscanf(buffer, "ACK:%d", &ack); if (ack == seq) { printf("[CLIENT] ACK received for seq=%d\n", seq); seq = 1 - seq; // toggle sequence number sent_packets++; } } sleep(1); } close(sockfd); return 0; }

Server

#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> int main() { char *ip = "127.0.0.1"; int port = 5555; int sockfd; struct sockaddr_in server_addr, client_addr; char buffer[1024]; socklen_t addr_size; int expected_seq = 0; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket error"); exit(1); } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr.s_addr = inet_addr(ip); if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind error"); exit(1); } printf("[SERVER] Stop-and-Wait ARQ Server running...\n"); while (1) { memset(buffer, 0, sizeof(buffer)); addr_size = sizeof(client_addr); recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &addr_size); int seq; sscanf(buffer, "DATA:%d", &seq); if (seq == expected_seq) { printf("[SERVER] Received DATA seq=%d\n", seq); expected_seq = 1 - expected_seq; } else { printf("[SERVER] Duplicate DATA seq=%d\n", seq); } // Simulate ACK loss if (rand() % 2 == 0) { memset(buffer, 0, sizeof(buffer)); sprintf(buffer, "ACK:%d", seq); printf("[SERVER] Sending ACK seq=%d\n", seq); sendto(sockfd, buffer, strlen(buffer) + 1, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); } else { printf("[SERVER] ACK lost (simulated)\n"); } sleep(1); } close(sockfd); return 0; }