使用线程将信息发送到分叉进程

时间:2019-11-28 10:24:00

标签: c multithreading tcp pthreads fork

我有2个程序,一个客户端和一个服务器,客户端可以将数据发送到服务器,并且我想通过线程将服务器上接收到的所有新数据从一个客户端发送到其他连接的客户端,每个线程客户端在接收数据的服务器中有一个子进程,这是我要执行的操作的说明。

server.c:

int  main(int argc, char const *argv[]) {
    Liste *ListeTache;
    int sh_id;
    int i,j;
    size_t sizeMatrix = sizeof_dm(30,100,sizeof(char));
    ListeTache=malloc(sizeof(Liste));
    init_Liste(ListeTache);

    key_t keyfile = ftok("keyFileIpc.txt",10);

    if((sh_id = shmget(keyfile,sizeof(Liste),IPC_CREAT|0666)) == -1) {
        perror("shmget");
        exit(1);
    }


    if ((ListeTache = shmat(sh_id, NULL, 0)) == (void *) -1) {
        perror("shmat");
        exit(1);
    }
    init_Liste(ListeTache);
    printSharedMem(ListeTache->s);
    //creation de la socket pour le TCP
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    if(sock == -1) {
        perror("socket error\n");
        exit(errno);
    }

    struct sockaddr_in sin = { 0 };

    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_family = PF_INET;
    sin.sin_port = htons(31470);

    if(bind (sock, (struct sockaddr *) &sin, sizeof sin) == -1) {
        perror("bind()");
        exit(errno);
    }

    if(listen(sock, 3) == -1) {
        perror("listen error\n");
        exit(errno);
    }

    struct sockaddr_in csin = { 0 };
    int idSock;
    socklen_t lg = sizeof(struct sockaddr_in);
    char msg[100];

    do {

        if ((idSock = accept(sock, (struct sockaddr *) &csin, &lg)) == -1) {
            perror("accept error\n");
            exit(errno);
        }

        if (!fork()) {
             close(sock);

            printSharedMem(ListeTache->s);
            printf("i'm here\n");
            // we send here the initial data
            if(send(idSock, ListeTache, sizeof(Liste), 0) < 0) {
              perror("send()");
              exit(errno);
            }
            pthread_t idThread;
            do {

                if(recv(idSock, &paramsReq, sizeof(paramsReq), 0) < 0) {
                    perror("paramsReq :recv error\n");
                    exit(errno);
                }
                  //if recv something from a client then i want to send the change to all the others here

        }
        else
         {
         close(idSock);
         }

    } while (1);

    free(ListeTache);
    ListeTache=NULL;
   shmctl(sh_id, IPC_RMID, NULL);
    return 0;
}

client.c

void *listenServ (void *arg) {
    paramsListenServ params = *((paramsListenServ *) arg);
    paramsRequest paramsReq;

    do {
        if(recv(params.sockId, &paramsReq, sizeof(paramsReq), 0) < 0) {
            perror("recv error\n");
            exit(errno);
        }
        printf("%s \n", paramsReq.requestType);
        if (!strcmp(paramsReq.requestType, "addRequest")) {
            strcpy(&params.s[paramsReq.taskToModify*100], paramsReq.taskText);

            printSharedMemo(params.s);
        }
        else if (!strcmp(paramsReq.requestType, "swapRequest")) {
            char firstTask[100];
            strcpy(firstTask, &params.s[paramsReq.tasksToSwap.firstTask*100]);

            strcpy(&params.s[paramsReq.tasksToSwap.firstTask*100], &params.s[paramsReq.tasksToSwap.secondTask*100]);
            strcpy(&params.s[paramsReq.tasksToSwap.secondTask*100], firstTask);

           printSharedMemo(params.s);
        }
        else if (!strcmp(paramsReq.requestType, "modifyRequest")) {
            strcpy(&params.s[paramsReq.taskToModify*100], paramsReq.taskText);

         printSharedMemo(params.s);
        }
        else if (!strcmp(paramsReq.requestType, "deleteRequest")) {
            int i = paramsReq.taskToModify;

            while (i < 29 && strlen(&params.s[i * 100]) != 0) {
                strcpy(&params.s[i*100], &params.s[(i + 1)*100]);
                i++;
            }

            strcpy(&params.s[(paramsReq.head - 1)*100], "");
            printSharedMemo(params.s);
        }

        /*printf("Message reçu du serveur : %s\n", msg);

        memset(msg,0, sizeof msg);*/
    } while (1);

    pthread_exit(NULL);
}


int main(int argc, char const *argv[]) {
    //creation d'un socket ppour le TCP
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    Liste *ListeTache;
    ListeTache=malloc(sizeof(Liste));
    init_Liste(ListeTache);
    int j;
    if(sock == -1) {
        perror("socket()");
        exit(errno);
    }

    //initialisation de la structure de donné
    struct sockaddr_in sin = { 0 };

    sin.sin_family = PF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_port = htons((short)31470);

    //connect to the server
    if(connect(sock,(struct sockaddr *) & sin, sizeof(struct sockaddr_in)) == -1) {
        perror("connect()");
        exit(errno);
    }

    // we receive the initial data
    if(recv(sock,ListeTache,sizeof(Liste), 0) < 0) {
        perror("main :recv error\n");
        exit(errno);
    }

    printSharedMemo(ListeTache->s);

    pthread_t idThread;

    paramsListenServ params;
    params.s=ListeTache->s;
    params.sockId = sock;

    // this thread listen to the send that is in the server
    if(pthread_create(&idThread, NULL, listenServ, &params) != 0)
        perror("pthread_create");
    do {

                //do changes

              //we send the new data to the server
            if(send(sock, &paramsReq, sizeof(paramsReq), 0) < 0) {
                perror("send()");
                exit(errno);
            }
        }
        }
    } while(1<=choice && choice<=4);
    close(sock);
    printf("La connexion avec le serveur a bien été fermée ! \n");
    return 0;
}

我的问题是,如果我使用线程并将其放在派生中,那么由于套接字从一个客户端更改为另一个客户端,该线程如何获取从一个客户端发送的数据?

0 个答案:

没有答案