我正在写一个可以处理多个客户端的聊天室。这是我第一次使用套接字进行编程,我在理解如何唯一地识别套接字时遇到了一些麻烦。以下是相关代码:
//set up child processes and allocate shared memory
int numprocesses = 0;
pid_t pids[10];
int shmid;
key_t key = 5678;
int *shm;
if ((shmid = shmget(key, 5000, IPC_CREAT | 0666)) < 0)
{
perror("shmget");
exit(1);
}
shm = (int *) shmat(shmid, NULL, 0);
//initialize shared memory to 0
for (int i = 0; i < 100; i++)
{
*(shm + i) = 0;
}
while(1)
{
//Accepting connections
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
perror("Error on accept");
exit(1);
}
printf("socket: %d\n", newsockfd);
//create a new process to handle each incoming connection
pids[numprocesses] = fork();
//child process
if ((pids[numprocesses] == 0))
{
*(shm + numprocesses) = newsockfd;
close(sockfd);
handle_client(newsockfd, shm);
exit(0);
}
//parent process
{
numprocesses++;
close(newsockfd);
}
}
出于某种原因,连接到聊天室的每个新客户端都有一个4的newsockfd,所以我不知道如何区分它们。任何帮助将非常感谢谢谢!
答案 0 :(得分:2)
套接字描述符在每个进程基础上被回收。
accept()
给你一个sd,然后你分叉客户端并关闭父母的sd并重新开始。由于sd已关闭,因此下次成功拨打accept()
可能会再次使用它。
当您为每个客户端分叉一个新流程时,process-id可能是一种识别客户端的方法,至少只要它已连接且其流程已存在。
要记录连接,这个(仅限pid)可能不起作用,因为process-id也可能被回收。因此,对于这种情况,您需要创建一些非常独特的连接ID,例如将pid与其创建的时间戳相结合。