簡體   English   中英

C 套接字編程:嘗試使用 fork() 提供新的客戶端連接

[英]C Socket Programming: Trying to serve new client connections using fork()

因此,每個客戶端連接都將在一個新的子進程上提供服務。

現在,我有一個 function generate_client() 創建一個客戶端並給它一個隨機的 ID 號(返回給客戶端)。

client_t generate_client()
{
    client_t *client = malloc(sizeof(client_t));

    client->clientID = randomClientIdGenerator(); < ----
    client->entryIndexConstant = 0;
    client->messageQueueIndex = 0;
    client->readMsg = 0;
    client->totalMessageSent = 0;
    client->unReadMsg = 0;
    client->status = CLIENT_INACTIVE;

    return *client;
}

int randomClientIdGenerator()
{
    int num = rand() % MAX_CLIENTS;
    return num;
}

問題:對於使用 fork() 的每個連接,子進程都是從父進程復制過來的,正如您在下面的實現中所見,具有相同客戶端 ID 的客戶端 object 被復制到子進程(至少這是我的想法正在發生)。

例如:使用終端 1 連接服務器生成客戶端 id 83,終端 2 連接也發送 id 83。

    /* bind the socket to the end point */
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("bind");
        exit(1);
    }

    /* start listnening */
    if (listen(sockfd, BACKLOG) == -1)
    {
        perror("listen");
        exit(1);
    }

    while (1)
    {

        sin_size = sizeof(struct sockaddr_in);
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
        if (new_fd == -1)
        {
            perror("accept.");
            printf("\n...error: accept new_fd failed\n");
            // continue;
        }

        printf("server: got connection from %s\n",
               inet_ntoa(their_addr.sin_addr));

        if (!fork())
        { /* this is the child process */
            printf("\n-----------------------CHILD START ----------\n");

            printf("\n child process id is %d. parent id is: %d\n", getpid(), getppid());

            /* ***Server-Client Connected*** */
            client_t client = generate_client();

            printf("\n =>client id %d STATUS: %d\n", client.clientID, client.status);

             if (client.clientID < -1)
            {
                perror("SERVER: failed to create client object (Max. 100 clients allowed)");
                printf("SERVER: failed to create client object (Max. 100 clients allowed) \n");
                exit(1);
                // send response to client Cant accept connection
            }

            // Send: Welcome Message.   ------------> SAME id of 83 is given to child process!!!
            if (send(new_fd, &client.clientID, sizeof(int), 0) == -1)
            {
                perror("send");
                printf("Error: Welcome message not sent to client \n");
           }
       }
}

我認為問題出在client_t client = generate_client(); 在 fork().. 里面生成從父進程復制過來的客戶端,我該如何在每個進程中重新調用它?

這似乎與幾個小時前發布的一個問題相同: 在新客戶端連接到服務器后嘗試 fork() [Socket Programming C]

簡短的回答:

“rand” function 使用隱藏的“狀態”來生成下一個隨機數。 由於父級從不使用 rand,因此每個分叉的子級將獲得相同的 state,並將生成相同的隨機數序列。

幾個可能的修復:

  • 在父級中調用 rand (在分叉之前)。 這將導致每個孩子從不同的 state 開始。
  • 在 fork 之前在 parent 中調用 rand,並保存 id 供孩子使用。
  • 使用 srand 為每個孩子設置隨機查看。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM