Here's a simple C program that demonstrates the Stop-and-Wait ARQ protocol. This basic implementation simulates the sender transmitting packets one at a time and waiting for an acknowledgment from the receiver. If the acknowledgment is not received, the sender retransmits the packet.
Key Points:
- The sender sends one packet at a time.
- If the receiver acknowledges it (ACK), the sender sends the next packet.
- If the acknowledgment is lost, the sender retransmits after a timeout.
C Program: Stop-and-Wait ARQ Simulation
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h> // for sleep()
#define TIMEOUT 3 // Timeout duration in seconds
#define TOTAL_PACKETS 5 // Number of packets to send
int simulate_acknowledgment() {
// Simulate a 70% chance of successful acknowledgment
return rand() % 10 < 7;
}
int main() {
srand(time(0)); // Seed for random number generation
int packet = 1;
int ack_received;
while (packet <= TOTAL_PACKETS) {
printf("Sender: Sending packet %d...\n", packet);
// Simulate waiting for acknowledgment
sleep(1); // Simulate transmission delay
ack_received = simulate_acknowledgment();
if (ack_received) {
printf("Receiver: ACK for packet %d received.\n\n", packet);
packet++; // Move to the next packet
} else {
printf("Receiver: ACK for packet %d lost! Retransmitting...\n\n", packet);
sleep(TIMEOUT); // Simulate timeout before retransmission
}
}
printf("All packets sent successfully!\n");
return 0;
}
Output
Sender: Sending packet 1...
gcc server.c -o server
Receiver: ACK for packet 1 received.
Sender: Sending packet 2...
Receiver: ACK for packet 2 lost! Retransmitting...
Sender: Sending packet 2...
Receiver: ACK for packet 2 received.
Sender: Sending packet 3...
Receiver: ACK for packet 3 received.
Sender: Sending packet 4...
Receiver: ACK for packet 4 lost! Retransmitting...
Sender: Sending packet 4...
Receiver: ACK for packet 4 received.
Sender: Sending packet 5...
Receiver: ACK for packet 5 received.
All packets sent successfully!
How the Program Works:
- Packets 1 to 5 are sent one by one.
- For each packet, there is a 70% chance that the acknowledgment will be received successfully.
- If the acknowledgment is lost, the program waits for 3 seconds (timeout) before retransmitting the same packet.
- This continues until all packets are successfully sent.
Notes:
- This is a simulation, so there are no real data transmissions involved.
- The
simulate_acknowledgment()
function mimics the random nature of packet loss or acknowledgment failure. - You can adjust
TOTAL_PACKETS
andTIMEOUT
to simulate different conditions.
Here's a simple Stop-and-Wait ARQ simulation using C socket programming to demonstrate communication between a client (sender) and a server (receiver).
Overview:
- Client sends packets to the server.
- The server randomly decides whether to acknowledge (ACK) or ignore (simulate ACK loss).
- The client retransmits if an acknowledgment is not received within a timeout.
Program Structure:
- Server: Waits for packets from the client, simulates acknowledgment or loss, and sends ACKs based on probability.
- Client: Sends packets, waits for ACK, and retransmits if no ACK is received within the timeout period.
Server Code (Receiver)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
int ack_prob = 70; // 70% chance of sending ACK
srand(time(0)); // Random seed for ACK simulation
// Create socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// Define server address
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Bind socket to port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
// Listen for incoming connections
if (listen(server_fd, 3) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("Server: Waiting for connection...\n");
// Accept connection from client
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
printf("Server: Connection established.\n");
while (1) {
// Receive packet from client
int valread = read(new_socket, buffer, BUFFER_SIZE);
if (valread == 0) break;
printf("Server: Received packet - %s\n", buffer);
// Simulate ACK or loss
if (rand() % 100 < ack_prob) {
printf("Server: ACK sent for packet %s\n\n", buffer);
send(new_socket, "ACK", strlen("ACK"), 0);
} else {
printf("Server: ACK lost for packet %s\n\n", buffer);
}
memset(buffer, 0, BUFFER_SIZE); // Clear buffer
}
close(new_socket);
close(server_fd);
return 0;
}
Client Code (Sender)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/time.h>
#define PORT 8080
#define BUFFER_SIZE 1024
#define TIMEOUT 3 // Timeout in seconds
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char buffer[BUFFER_SIZE] = {0};
char packet[50];
struct timeval tv;
// Create socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IP address
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
perror("Invalid address or Address not supported");
exit(EXIT_FAILURE);
}
// Connect to server
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Client: Connected to server.\n");
// Set socket timeout
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
int packet_number = 1;
while (packet_number <= 5) {
sprintf(packet, "%d", packet_number);
printf("Client: Sending packet %d...\n", packet_number);
send(sock, packet, strlen(packet), 0);
// Wait for ACK
int valread = read(sock, buffer, BUFFER_SIZE);
if (valread > 0 && strcmp(buffer, "ACK") == 0) {
printf("Client: ACK received for packet %d\n\n", packet_number);
packet_number++;
} else {
printf("Client: Timeout! Retransmitting packet %d...\n\n", packet_number);
}
memset(buffer, 0, BUFFER_SIZE); // Clear buffer
}
printf("Client: All packets sent successfully.\n");
close(sock);
return 0;
}
How to Run the Program:
Compile the Server and Clientgcc server.c -o server
gcc client.c -o client
Run the Server
./server
./server
Run the Client (in a new terminal)
./client
Sample output - Server
./client
Sample output - Server
Server: Waiting for connection...
Server: Connection established.
Server: Received packet - 1
Server: ACK sent for packet 1
Server: Received packet - 2
Server: ACK lost for packet 2
Server: Received packet - 2
Server: ACK sent for packet 2
Sample output - Client
Client: Connected to server.
Client: Sending packet 1...
Client: ACK received for packet 1
Client: Sending packet 2...
Client: Timeout! Retransmitting packet 2...
Client: ACK received for packet 2
Key Points:
- Simulates Stop-and-Wait ARQ over a network using TCP sockets.
- Timeout and ACK loss simulation added for retransmission testing.
- Simple, extendable, and great for demonstrating basic error control in networks.
Comments
Post a Comment