【问题标题】:C Socket Programming: Trying to serve new client connections using fork()C Socket 编程:尝试使用 fork() 提供新的客户端连接
【发布时间】:2019-10-19 02:57:16
【问题描述】:

因此每个客户端连接都将在一个新的子进程上提供服务。

现在,我有一个函数 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 的 客户端对象转到子进程(至少这是我认为正在发生的事情)。

例如:使用终端 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(); inside fork().. 它生成从父进程复制过来的客户端,我该如何在每个进程中重新调用它?

【问题讨论】:

  • 您在发送后忘记exit/_exit您的孩子。

标签: c sockets concurrency process fork


【解决方案1】:

这似乎与几小时前发布的问题相同: Trying to fork() after new client connection to server [Socket Programming C]

简答:

“rand”函数使用隐藏的“状态”来生成下一个随机数。由于父级从不使用 rand,因此每个分叉的子级将获得相同的状态,并生成相同的随机数序列。

一些可能的修复:

  • 在父节点中调用 rand (在分叉之前)。这将导致每个孩子从不同的状态开始。
  • 在分叉之前在父级中调用 rand,并保存 id 以供子级使用。
  • 使用 srand 为每个孩子设置随机查看。

【讨论】:

    猜你喜欢
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 2016-09-15
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    相关资源
    最近更新 更多