gpt4 book ai didi

C套接字编程: Trying to serve new client connections using fork()

转载 作者:行者123 更新时间:2023-11-30 19:25:43 25 4
gpt4 key购买 nike

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

现在,我有一个函数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");
}
}
}

我认为问题出在 fork() 内部的 client_t client =generate_client(); ..它生成从父进程复制过来的客户端,如何做我可能会在每个进程中重新调用它?

最佳答案

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

简短回答:

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

一些可能的修复:

  • 在父级中对 rand 进行一次调用(在 fork 之前)。这将导致每个 child 从不同的状态开始。
  • 在 fork 之前在父级中调用 rand,并保存 id 供子级使用。
  • 使用 srand 为每个子项设置随机查看。

关于C套接字编程: Trying to serve new client connections using fork(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58460152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com