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
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;
}