Untitled

 avatar
unknown
plain_text
2 years ago
3.6 kB
2
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

#define NUM_MODULES 5

int priorities[NUM_MODULES] = {5, 4, 3, 2, 1}; // Priorities for each module
int leader = -1; // Leader module ID
int election_in_progress = 0; // Flag to indicate if an election is in progress
int module_id = -1; // ID of this module
int sockfd; // Socket file descriptor

void send_message(char* message, struct sockaddr_in addr) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    sendto(sock, message, strlen(message), 0, (struct sockaddr*)&addr, sizeof(addr));
    close(sock);
}

void* receive_messages(void* arg) {
    char buffer[1024];
    struct sockaddr_in addr;
    socklen_t addr_len = sizeof(addr);
    while(1) {
        recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr*)&addr, &addr_len);
        if(strncmp(buffer, "ELECTION", strlen("ELECTION")) == 0) {
            int sender_id = buffer[strlen("ELECTION")];
            if(priorities[sender_id] > priorities[module_id]) {
                // Higher priority module is initiating an election
                election_in_progress = 1;
                send_message("OK", addr);
                leader = -1;
            }
        } else if(strncmp(buffer, "OK", strlen("OK")) == 0) {
            if(election_in_progress) {
                // Received an OK during an election
                int sender_id = buffer[strlen("OK")];
                if(priorities[sender_id] > priorities[module_id]) {
                    // Higher priority module is willing to take over as leader
                    election_in_progress = 0;
                }
            }
        } else if(strncmp(buffer, "LEADER", strlen("LEADER")) == 0) {
            int sender_id = buffer[strlen("LEADER")];
            leader = sender_id;
            election_in_progress = 0;
        }
    }
}

void* initiate_election(void* arg) {
    while(1) {
        if(leader == -1 && !election_in_progress) {
            election_in_progress = 1;
            for(int i = 0; i < NUM_MODULES; i++) {
                if(priorities[i] > priorities[module_id]) {
                    // Send election message to higher priority modules
                    struct sockaddr_in addr;
                    addr.sin_family = AF_INET;
                    addr.sin_port = htons(5000+i);
                    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
                    send_message("ELECTION", addr);
                }
            }
        }
        sleep(5); // Wait 5 seconds before initiating another election
    }
}

int main(int argc, char** argv) {
    if(argc != 2) {
        printf("Usage: %s <module id>\n", argv[0]);
        return 1;
    }
    module_id = atoi(argv[1]);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(5000+module_id);
    addr.sin_addr.s_addr = INADDR_ANY;
    bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    pthread_t receive_thread, election_thread;
    pthread_create(&receive_thread, NULL, receive_messages, NULL);
    pthread_create(&election_thread, NULL, initiate_election, NULL);
    while(1) {
        if(leader == module_id) {
            printf("I am the leader!\n");
        } else if(leader != -1) {
            printf("The leader is module %d.\n", leader);
        }
        sleep(10); // Wait 10 seconds before printing leader information again
    }
    return 0;
}