UDP多客户端服务器

时间:2017-12-19 14:36:08

标签: c linux sockets udp

问题是让UDP服务器将数据发送到已经与服务器建立连接的客户端阵列。所有客户端IP都存储在服务器端链表中,但由于某种原因,我只能发送响应,而且只能发送到客户端的最后连接。

所以我想要实现的基本描述是:

  1. 很少有客户建立连接,我可以看到他们的消息

  2. 每个客户的IP都存储在链表

  3. 如果在链表中存储了多个客户端,则程序将遍历其存储中的每个IP,并且如果当前客户端的IP与存储在链表中的IP不同 - >服务器从当前客户端发送到此IP最后一条消息
  4. 在服务器端,如果输入了消息,程序将遍历LinkedList中存储的每个IP并将此消息发送给每个客户端
  5. server.c

    #include "server.h"
    #include "linkedList.h"
    
    volatile sig_atomic_t dones = 0;
    
    void server(){
        pthread_t r, s;
        int server_d;
        struct sockaddr_in server, client;
        struct params args;
    
        linkedList** iter = getIteratorList();
    
        if((server_d = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
            perror("\nsocket");
            exit(-1);
        }
    
        server.sin_family = AF_INET;
        server.sin_port = htons(PORT);
        server.sin_addr.s_addr = INADDR_ANY;
        bzero(server.sin_zero, 8);
    
        args.client = &client;
        args.server_d = &server_d;
        args.iter = iter;
    
        if(bind(server_d, (struct sockaddr*)&server, sizeof(struct sockaddr)) == -1){
            perror("\nbind");
            exit(-1);
        }
    
        pthread_create(&r, NULL, receives, (void*)&args);
        pthread_create(&s, NULL, sends, (void*)&args);
        pthread_join(s, NULL);
    
    }
    
    void* receives(void* data){
    
        int flag = 0;
        struct params* args = data;
        int* server_d = args->server_d;
        struct sockaddr_in* client = args->client;
        linkedList** iter = args->iter;
        unsigned int length = sizeof(struct sockaddr_in);
        char buffer[BUFFER_MAX];
        struct sockaddr_in tmp;
    
    
        struct sigaction action;
        memset(&action, 0, sizeof(struct sigaction));
        action.sa_handler = terms;
        sigaction(SIGINT, &action, NULL);
    
        bzero(buffer, BUFFER_MAX);
    
        while(!dones){
    
            if(flag == 0){
                if(recvfrom(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)client, &length) > 0){
                    flag = 1;
                    decrypt(buffer);
                    printf("[%s]:%s", inet_ntoa(client->sin_addr), buffer);
    
    
                    //some new staff
    
    
    
    
    
                    if(checkList(inet_ntoa(client->sin_addr)) != 1){
                        addList(*client);
                        printf("[DEBUG]clients IP is stored. size of LL: %d\n", sizeList());
                    }
                    if(sizeList() > 1){
                        beginList();
                        for(int i = 0; i < sizeList(); i++){
                            printf("[DEBUG]Stored IP[%d]: %s\n", i, (*iter)->address);
                            nextList();
                            }
                    }
                        beginList();
                        for(int i = 0; i < sizeList(); i++){
                            if (strcmp((*iter)->address, inet_ntoa(client->sin_addr)) != 0){
    
                                printf("[DEBUG]there is a client to send a message to. message: %s", buffer);
    
                                printf("[DEBUG]resend: %s --> %s\n",inet_ntoa(client->sin_addr), (*iter)->address);
    
                                tmp.sin_addr.s_addr = inet_addr((*iter)->address);
                                tmp.sin_family = client->sin_family;
                                tmp.sin_port = client->sin_port;
                                bzero(tmp.sin_zero, 8);
    
                                printf("[DEBUG]IP in tmp.sin_addr: %s\n", inet_ntoa(tmp.sin_addr));
                                printf("[DEBUG]IP in client->sin_addr: %s\n", inet_ntoa(client->sin_addr));
    
                                printf("[DEBUG]message send: %d\n", (int)sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)&tmp, sizeof(struct sockaddr_in)));
                                nextList();
                            }else{
                                nextList();
                            }
                        }
    
    
    
    
    
    
    
    
    
    
                    // end of new staff
    
                }
                bzero(buffer, BUFFER_MAX);
            }else{
                if(recvfrom(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)client, &length) == 0){
                    flag = 0;
                }else{
                    decrypt(buffer);
                    printf("[%s]:%s", inet_ntoa(client->sin_addr), buffer);
    
    
    
    
    
                    //some new staff
    
    
    
    
    
    
    
    
    
    
    
    
                    if(checkList(inet_ntoa(client->sin_addr)) != 1){
                        addList(*client);
                        printf("[DEBUG]clients IP is stored. size of LL: %d\n", sizeList());
                    }
                    if(sizeList() > 1){
                        beginList();
                        for(int i = 0; i < sizeList(); i++){
                            printf("[DEBUG]Stored IP[%d]: %s\n", i, (*iter)->address);
                            nextList();
                            }
                    }
                        beginList();
                        for(int i = 0; i < sizeList(); i++){
                            if (strcmp((*iter)->address, inet_ntoa(client->sin_addr)) != 0){
    
                                printf("[DEBUG]there is a client to send a message to. message: %s", buffer);
    
                                printf("[DEBUG]resend: %s --> %s\n",inet_ntoa(client->sin_addr), (*iter)->address);
    
                                tmp.sin_addr.s_addr = inet_addr((*iter)->address);
                                tmp.sin_family = client->sin_family;
                                tmp.sin_port = client->sin_port;
                                bzero(tmp.sin_zero, 8);
    
                                printf("[DEBUG]IP in tmp.sin_addr: %s\n", inet_ntoa(tmp.sin_addr));
                                printf("[DEBUG]IP in client->sin_addr: %s\n", inet_ntoa(client->sin_addr));
    
                                printf("[DEBUG]message send: %d\n", (int)sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)&tmp, sizeof(struct sockaddr_in)));
                                nextList();
                            }else{
                                nextList();
                            }
                        }
    
    
    
    
    
    
    
    
    
    
                    // end of new staff
    
                }
                bzero(buffer, BUFFER_MAX);
            }
    
        }
    
        printf("Server terminated.\n");
    
        return NULL;
    }
    
    void* sends(void* data){
    
        struct params* args = data;
        int* server_d = args->server_d;
        struct sockaddr_in* client = args->client;
        linkedList** iter = args->iter;
        char buffer[BUFFER_MAX];
        struct sockaddr_in tmp;
    
        struct sigaction action;
        memset(&action, 0, sizeof(struct sigaction));
        action.sa_handler = terms;
        sigaction(SIGINT, &action, NULL);
    
        while(!dones){
    
            bzero(buffer, BUFFER_MAX);
            fgets(buffer, BUFFER_MAX - 1, stdin);
    
            encrypt(buffer);
    /*
            if(sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)client, sizeof(struct sockaddr_in)) == -1){
                printf("Message was not sent...\n");
            }
    */
    
    
            tmp.sin_addr.s_addr = client->sin_addr.s_addr;
            tmp.sin_family = client->sin_family;
            tmp.sin_port = client->sin_port;
            bzero(tmp.sin_zero, 8);
    
            beginList();
            for(int i = 0; i < sizeList(); i++){
                tmp.sin_addr.s_addr = inet_addr((*iter)->address);
                printf("[DEBUG]sending to address: %s\n", inet_ntoa(tmp.sin_addr));
                sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)&tmp, sizeof(struct sockaddr_in));
                nextList();
            }
    
        }
    
        printf("Server terminated.\n");
    
        return NULL;
    }
    
    void terms(int signum){
    
        dones = 1;
        if(clearList() == 0) printf("\n\nLinkedList was succesfully deleted.\n");
        printf("\nTerminating server...\n");
    
    }
    

    server.h

    #ifndef SERVER_H_
    #define SERVER_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <pthread.h>
    #include <signal.h>
    #include "const.h"
    #include "encrypt.h"
    #include "linkedList.h"
    
    struct params{
        struct sockaddr_in* client;
        int* server_d;
        linkedList** iter;
    };
    
    volatile sig_atomic_t dones;
    
    void server();
    void* receives(void*);
    void* sends(void*);
    void terms(int);
    
    #endif
    

    linkedList.h

    #ifndef LINKED_LIST_
    #define LINKED_LIST_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    typedef struct ll{
    
        int socket;
        char* address;
        struct ll* next;
        struct ll* prev;
    
    } linkedList;
    
    
    linkedList* initList(struct sockaddr_in);
    linkedList* addList(struct sockaddr_in);
    linkedList* removeList(char*);
    unsigned short int clearList();
    unsigned short int sizeList();
    linkedList* nextList();
    linkedList* prevList();
    linkedList* beginList();
    linkedList* endList();
    linkedList** getIteratorList();
    unsigned short int checkList(char*);
    
    
    #endif
    

    linkedList.c

    #include "linkedList.h"
    
    static linkedList* iterator = NULL;
    
    linkedList* initList(struct sockaddr_in p_new){
    
        iterator = (linkedList*) malloc(sizeof(linkedList));
        if(iterator == NULL) return NULL;
        iterator->next = NULL;
        iterator->prev = NULL;
        iterator->address = (char*)malloc(sizeof(char)*16);
        strcpy(iterator->address, inet_ntoa(p_new.sin_addr));
        return iterator;
    
    }
    linkedList* addList(struct sockaddr_in p_new){
    
        if(iterator == NULL){
    
            return initList(p_new);
    
        }
        endList();
        iterator->next = (linkedList*) malloc(sizeof(linkedList));
        if(iterator->next == NULL) return NULL;
        iterator->next->next = NULL;
        iterator->next->prev = iterator;
        iterator->next->address = (char*)malloc(sizeof(char)*16);
        strcpy(iterator->next->address, inet_ntoa(p_new.sin_addr));
        return iterator = iterator->next;
    
    }
    linkedList* removeList(char* p_address){
    
        beginList();
        for(int i = 0; i < sizeList(); i++){
            if(strcmp(iterator->address, p_address) == 0){
    
                if(iterator->prev == NULL){
    
                    iterator = iterator->next;
                    free(iterator->prev->address);
                    free(iterator->prev);
                    iterator->prev = NULL;
                    return iterator;
    
                }else if(iterator->next == NULL){
    
                    iterator = iterator->prev;
                    free(iterator->next->address);
                    free(iterator->next);
                    iterator->next = NULL;
                    return iterator;
    
                }else{
    
                    linkedList* tmp = iterator->next;
                    iterator->prev->next = iterator->next;
                    iterator->next->prev = iterator->prev;
                    free(iterator->address);
                    free(iterator);
                    return iterator = tmp;
    
                }
    
    
            }else{
                nextList();
            }
        }
        beginList();
        return iterator;
    }
    unsigned short int clearList(){
    
        if (iterator == NULL) return 404;
    
        endList();
    
        while( (iterator->next != NULL && iterator->prev != NULL) ){
    
            iterator = iterator->prev;
            free(iterator->next->address);
            free(iterator->next);
            iterator->next = NULL;
    
        }
    
        free(iterator);
        iterator = NULL;
        return 0;
    
    }
    unsigned short int sizeList(){
    
        unsigned short int size = 0;
        unsigned int tmp_range = 0;
        if(iterator == NULL) return size;
        while(iterator->prev != NULL){
            tmp_range++;
            prevList();
        }
    
        while(iterator->next != NULL){
            size++;
            nextList();
        }
        size++;
        beginList();
        for(int i = 0; i < tmp_range; i++){
            nextList();
        }
        return size;
    
    }
    linkedList* nextList(){
    
        if (iterator == NULL) return NULL;
    
        if(iterator->next == NULL) return iterator; else return iterator = iterator->next;
    
    }
    linkedList* prevList(){
    
        if (iterator == NULL) return NULL;
    
        if(iterator->prev == NULL) return iterator; else return iterator = iterator->prev;
    
    }
    linkedList* beginList(){
    
        if (iterator == NULL) return NULL;
    
        while(iterator->prev != NULL){
            prevList();
        }
    
        return iterator;
    
    }
    linkedList* endList(){
    
        if (iterator == NULL) return NULL;
    
        while(iterator->next != NULL){
            nextList();
        }
    
        return iterator;
    
    }
    linkedList** getIteratorList(){
        return &iterator;
    }
    unsigned short int checkList(char* p_str){
    
        if(iterator == NULL) return 0;
    
        beginList();
        for(int i = 0; i < sizeList(); i++){
            if(strcmp(iterator->address, p_str) == 0){
    
                return 1;
    
            }else nextList();
        }
        beginList();
        return 0;
    }
    

    client.h

    #ifndef CLIENT_H_
    #define CLIENT_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <pthread.h>
    #include <signal.h>
    #include "const.h"
    #include "encrypt.h"
    
    struct paramc{
        struct sockaddr_in* server;
        int* client_d;
    };
    
    volatile sig_atomic_t donec;
    
    void client(char*);
    void* receivec(void*);
    void* sendc(void*);
    void termc(int);
    
    #endif
    

    client.c

    #include "client.h"
    
    volatile sig_atomic_t donec = 0;
    
    void client(char* address){
    
        pthread_t r, s;
        int client_d;
        struct sockaddr_in server;
        struct paramc args;
    
        if((client_d = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
            perror("\nsocket");
            exit(-1);
        }
    
        server.sin_family = AF_INET;
        server.sin_port = htons(PORT);
        server.sin_addr.s_addr = inet_addr(address);
        bzero(server.sin_zero, 8);
    
    
        args.server = &server;
        args.client_d = &client_d;
    
        pthread_create(&r, NULL, receivec, (void*)&args);
        pthread_create(&s, NULL, sendc, (void*)&args);
        pthread_join(s, NULL);
    
    }
    
    void* receivec(void* data){
    
        struct paramc* args = data;
        struct sockaddr_in* server = args->server;
        int* client_d = args->client_d;
        unsigned int length = sizeof(struct sockaddr_in);
        char buffer[BUFFER_MAX];
    
        struct sigaction action;
        memset(&action, 0, sizeof(struct sigaction));
        action.sa_handler = termc;
        sigaction(SIGINT, &action, NULL);
    
        while(!donec){
    
            if(recvfrom(*client_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)server, &length) > 0){
                decrypt(buffer);
                printf("[%s]:%s", inet_ntoa(server->sin_addr), buffer);
                bzero(buffer, BUFFER_MAX);
            }
    
        }
    
        printf("Client terminated.\n");
    
        return NULL;
    }
    
    void* sendc(void* data){
    
        struct paramc* args = data;
        struct sockaddr_in* server = args->server;
        int* client_d = args->client_d;
        char buffer[BUFFER_MAX];
    
        struct sigaction action;
        memset(&action, 0, sizeof(struct sigaction));
        action.sa_handler = termc;
        sigaction(SIGINT, &action, NULL);
    
        while(!donec){
    
            bzero(buffer, BUFFER_MAX);
            fgets(buffer, BUFFER_MAX - 1, stdin);
    
            encrypt(buffer);
    
            sendto(*client_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)server, sizeof(struct sockaddr_in));
    
        }
    
        printf("Client terminated.\n");
    
        return NULL;
    }
    
    void termc(int signum){
    
        donec = 1;
        printf("\nTerminating client...\n");
    
    }
    

    const.h

    #ifndef CONST_H_
    #define CONST_H_
    
    #define PORT 15151
    #define BUFFER_MAX 1024
    
    #endif
    

    的main.c

    #include "server.h"
    #include "client.h"
    
    //#define linkedlist_test
    #ifdef linkedlist_test
    #include "linkedList.h"
    #endif
    
    int main(int argc, char* argv[]){
    
    
    #ifndef linkedlist_test
        system("clear");
    
        if(argc < 2){
    
            server();
    
        }else{
    
            client(argv[1]);
    
        }
    #endif
    #ifdef linkedlist_test
        struct sockaddr_in test1;
        test1.sin_family = AF_INET;
        test1.sin_port = htons(PORT);
        test1.sin_addr.s_addr = inet_addr("192.168.1.101");
        bzero(test1.sin_zero, 8);
    
        struct sockaddr_in test2;
        test2.sin_family = AF_INET;
        test2.sin_port = htons(PORT);
        test2.sin_addr.s_addr = inet_addr("192.168.1.102");
        bzero(test2.sin_zero, 8);
    
        struct sockaddr_in test3;
        test3.sin_family = AF_INET;
        test3.sin_port = htons(PORT);
        test3.sin_addr.s_addr = inet_addr("192.168.1.103");
        bzero(test3.sin_zero, 8);
    
        struct sockaddr_in test4;
        test4.sin_family = AF_INET;
        test4.sin_port = htons(PORT);
        test4.sin_addr.s_addr = inet_addr("192.168.1.104");
        bzero(test4.sin_zero, 8);
    
        struct sockaddr_in test5;
        test5.sin_family = AF_INET;
        test5.sin_port = htons(PORT);
        test5.sin_addr.s_addr = inet_addr("192.168.1.105");
        bzero(test5.sin_zero, 8);
    
        linkedList** iterator = getIteratorList();
        printf("address: %p/%p\torder: %d\n", *iterator, addList(test1), sizeList());
        printf("address: %p/%p\torder: %d\n", *iterator, addList(test2), sizeList());
        printf("address: %p/%p\torder: %d\n", *iterator, addList(test3), sizeList());
        printf("address: %p/%p\torder: %d\n", *iterator, addList(test4), sizeList());
        printf("address: %p/%p\torder: %d\n", *iterator, addList(test5), sizeList());
    
        printf("vypis testovych struktur priamo:\n%s\n", inet_ntoa(test1.sin_addr));
        printf("%s\n", inet_ntoa(test2.sin_addr));
        printf("%s\n", inet_ntoa(test3.sin_addr));
        printf("%s\n", inet_ntoa(test4.sin_addr));
        printf("%s\n", inet_ntoa(test5.sin_addr));
    
        printf("========================\n");
        checkList("192.168.1.104");
        printf("checkList() test: adresa -//-.104 sa nachadza: %p, plna adresa je %s\n", (*iterator), (*iterator)->address);
    
        beginList();
        for(int i = 0; i < sizeList(); i++){
            printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
            nextList();
        }
        printf("========================\n");
    
        removeList("192.168.1.102");
        printf("deleting 192.168.1.102\n");
        printf("size: %d\n", sizeList());
    
    
        beginList();
        for(int i = 0; i < sizeList(); i++){
            printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
            nextList();
        }
        printf("========================\n");
        removeList("192.168.1.101");
        printf("deleting 192.168.1.101\n");
        printf("size: %d\n", sizeList());
    
        beginList();
        for(int i = 0; i < sizeList(); i++){
            printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
            nextList();
        }
    
        printf("========================\n");
        removeList("192.168.1.105");
        printf("deleting 192.168.1.105\n");
        printf("size: %d\n", sizeList());
    
    
    
        beginList();
        for(int i = 0; i < sizeList(); i++){
            printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
            nextList();
        }
        printf("========================\n");
    
        printf("removing the whole list\n");
        if(clearList() == 0) printf("successfully removed\n"); else printf("some chiki-briki is not right. FAILUREEE!");
        printf("size: %d\n", sizeList());
        printf("========================\n");
    #endif
        return 0;
    }
    

    encrypt.c和encrypt.h只是两个函数char * encrypt(char *)和char * decrypt(char *),它们不对字符串做任何事情 - &gt; WIP

0 个答案:

没有答案