Advertisement
Solingen

lab5_zadanie8

May 22nd, 2024
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.84 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <arpa/inet.h>
  6. #include <pthread.h>
  7.  
  8. #define MAX_MSG_SIZE 500
  9. #define MAX_NAME_SIZE 50
  10.  
  11. pthread_mutex_t friends_mutex = PTHREAD_MUTEX_INITIALIZER;
  12.  
  13. typedef struct {
  14.     char name[MAX_NAME_SIZE];
  15.     struct sockaddr_in addr;
  16. } Friend;
  17.  
  18. Friend *friends = NULL;
  19. int num_friends = 0;
  20. int sock;
  21. char user_name[MAX_NAME_SIZE];
  22.  
  23. void add_friend(const char *name, struct sockaddr_in *addr) {
  24.     pthread_mutex_lock(&friends_mutex);
  25.     Friend *temp = realloc(friends, (num_friends + 1) * sizeof(Friend));
  26.     if (temp != NULL) {
  27.         friends = temp;
  28.         strcpy(friends[num_friends].name, name);
  29.         friends[num_friends].addr = *addr;
  30.         num_friends++;
  31.         //printf("Added friend: %s %s %d\n", name, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
  32.     } else {
  33.         printf("Memory allocation failed!\n");
  34.     }
  35.     pthread_mutex_unlock(&friends_mutex);
  36. }
  37.  
  38. int is_friend(struct sockaddr_in *addr) {
  39.     int found = 0;
  40.     pthread_mutex_lock(&friends_mutex);
  41.     for (int i = 0; i < num_friends; i++) {
  42.         if (friends[i].addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
  43.             friends[i].addr.sin_port == addr->sin_port) {
  44.             found = 1;
  45.             break;
  46.         }
  47.     }
  48.     pthread_mutex_unlock(&friends_mutex);
  49.     return found;
  50. }
  51.  
  52. void send_message(const char *msg, struct sockaddr_in *addr);
  53.  
  54. void *receive_messages(void *arg) {
  55.     struct sockaddr_in src_addr;
  56.     socklen_t addr_len = sizeof(src_addr);
  57.     char buffer[MAX_MSG_SIZE];
  58.  
  59.     while (1) {
  60.         int msg_len = recvfrom(sock, buffer, MAX_MSG_SIZE, 0, (struct sockaddr *)&src_addr, &addr_len);
  61.         if (msg_len > 0) {
  62.             buffer[msg_len] = '\0';
  63.             char *name = buffer;
  64.             char *msg = buffer + strlen(name) + 1;
  65.  
  66.             if (strcmp(msg, "#hi!") == 0) {
  67.                 send_message("#hey!", &src_addr);
  68.             } else if (strcmp(msg, "#hey!") == 0) {
  69.                 if (!is_friend(&src_addr)) {
  70.                     add_friend(name, &src_addr);
  71.                 }
  72.             } else {
  73.                 printf("%s: %s\n", name, msg);
  74.             }
  75.         }
  76.     }
  77.     return NULL;
  78. }
  79.  
  80. void send_message(const char *msg, struct sockaddr_in *addr) {
  81.     char buffer[MAX_MSG_SIZE];
  82.     snprintf(buffer, MAX_MSG_SIZE, "%s%c%s%c", user_name, '\0', msg, '\0');
  83.     sendto(sock, buffer, strlen(user_name) + 1 + strlen(msg) + 1, 0, (struct sockaddr *)addr, sizeof(*addr));
  84. }
  85.  
  86. void send_to_all(const char *msg) {
  87.     pthread_mutex_lock(&friends_mutex);
  88.     for (int i = 0; i < num_friends; i++) {
  89.         send_message(msg, &friends[i].addr);
  90.     }
  91.     pthread_mutex_unlock(&friends_mutex);
  92. }
  93.  
  94. void handle_command(const char *command) {
  95.     if (strncmp(command, "@hi", 3) == 0) {
  96.         char ip[INET_ADDRSTRLEN];
  97.         int port;
  98.         sscanf(command + 4, "%s %d", ip, &port);
  99.         struct sockaddr_in new_friend;
  100.         new_friend.sin_family = AF_INET;
  101.         new_friend.sin_port = htons(port);
  102.         inet_pton(AF_INET, ip, &new_friend.sin_addr);
  103.         send_message("#hi!", &new_friend);
  104.         //printf("Sent @hi to %s %d\n", ip, port);
  105.     } else if (strcmp(command, "@friends") == 0) {
  106.         pthread_mutex_lock(&friends_mutex);
  107.         for (int i = 0; i < num_friends; i++) {
  108.             printf("%s %s %d\n", friends[i].name, inet_ntoa(friends[i].addr.sin_addr), ntohs(friends[i].addr.sin_port));
  109.         }
  110.         pthread_mutex_unlock(&friends_mutex);
  111.     } else if (strcmp(command, "@exit") == 0) {
  112.         close(sock);
  113.         exit(0);
  114.     }
  115. }
  116.  
  117. int main(int argc, char *argv[]) {
  118.     if (argc != 3) {
  119.         fprintf(stderr, "Usage: %s <name> <port>\n", argv[0]);
  120.         exit(1);
  121.     }
  122.  
  123.     friends = (Friend *)malloc(sizeof(Friend) * 10);
  124.     if (friends == NULL) {
  125.         perror("Error allocating memory for friends list");
  126.         exit(1);
  127.     }
  128.  
  129.     strcpy(user_name, argv[1]);
  130.     int port = atoi(argv[2]);
  131.  
  132.     sock = socket(AF_INET, SOCK_DGRAM, 0);
  133.     if (sock == -1) {
  134.         perror("Error creating socket");
  135.         exit(1);
  136.     }
  137.  
  138.     struct sockaddr_in server_addr;
  139.     server_addr.sin_family = AF_INET;
  140.     server_addr.sin_addr.s_addr = INADDR_ANY;
  141.     server_addr.sin_port = htons(port);
  142.  
  143.     if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
  144.         perror("Error binding socket");
  145.         exit(1);
  146.     }
  147.  
  148.     pthread_t recv_thread;
  149.     pthread_create(&recv_thread, NULL, receive_messages, NULL);
  150.  
  151.     char input[MAX_MSG_SIZE];
  152.     while (1) {
  153.         fgets(input, sizeof(input), stdin);
  154.         input[strcspn(input, "\n")] = '\0';
  155.         if (input[0] == '@') {
  156.             handle_command(input);
  157.         } else {
  158.             send_to_all(input);
  159.         }
  160.     }
  161.  
  162.     free(friends);
  163.     close(sock);
  164.     return 0;
  165. }
  166.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement