我在UNIX上用UNIX编写程序。我必须在套接字上编写客户端 - 服务器(TCP)程序。客户端发送一些信息和服务器答案。无论客户端发送或接收什么,因为我成功为其编写代码。但是最后一部分任务对我来说很难。
1)一个连接 - 一个子进程。
2)对于使用池中预运行进程的新连接。
3)池大小是dinamic。如果自由进程(不是服务客户端)的数量变得小于N - 应创建新进程,如果它变得超过K - “额外”进程必须终止
这是我的代码。每个连接都使用fork()
创建新的子进程。每个连接都在新进程中运行。但是如何制作我上面说过的动态池呢?
请帮助,这非常重要!这是我应该做的最后一次。
服务器代码:
int main(int argc, char * argv[])
{
int cfd;
int listener = socket(AF_INET, SOCK_STREAM, 0); //create listiner socket
if(listener < 0){
perror("socket error");
return 1;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int binding = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
if(binding < 0){
perror("binding error");
return 1;
}
listen(listener, 1); //listen for new clients
signal(SIGCHLD,handler);
int pid;
for(;;) // infinity loop on server
{
cfd = accept(listener, NULL, NULL); //client socket descriptor
pid = fork(); //make child proc
if(pid == 0) //in child proc...
{
close(listener); //close listener socket descriptor
... //some server actions that I do.(receive or send)
close(cfd); // close client fd
return 0;
}
close(cfd);
}
return 0;
}
答案 0 :(得分:3)
这是一个设计或架构问题,对于使用代码的明确答案而言过于宽泛。
因此,您知道您希望在自己的进程中为每个新连接提供服务。你的另外两个限制(至少)提出了两个问题:
首先,如何将新连接路由到N个已经在运行的工作人员之一?
这相对容易。这里最常见的设计是:
其次,我们如何确保 N - K 空闲工作进程可用?
这是一个更大的问题,你必须根据自己的舒适度和任何其他限制来回答。
您需要知道,不仅仅有多少工人还活着,而是哪些工人闲着(&#34;免费&#34;)。让父母进程跟踪其子女是一个明显的开始,但这并不能让闲散的工人与忙碌的工人区别开来。您可以使用共享的互斥状态表,文件还是共享内存?或者也许每个孩子通过socketpair()(与文件描述符传递相同)传递给父母的状态?
然后,如果由于某种原因你超过 K ,你如何安全地杀死一个空闲工人?信号?在同一个socketpair()上给出的命令?新闲工作者是否可以检查状态表是否自动终止,如果闲置将超过 K ?你如何从意外的工人终止中恢复(例如,SEGV)?等等。
Apache的MPM prefork模块在此问题空间中实现了一种可能的设计。您可能想咨询它以获取想法。
答案 1 :(得分:1)
您的代码似乎不满足条件编号2.您的进程池未预先运行。接受连接时会创建进程。一种解释是你会做一堆分叉,然后让分叉的进程等待接受。一个人会得到它,然后它会进行处理。
父进程需要跟踪有多少孩子。你可以在一个等待的线程中执行此操作。这将等待孩子死亡。 (请参阅man 2等待各种口味。)当进程数量变得太大时,您可以发送一个孩子可以捕获的信号以便正确终止。但是,我假设父进程不会分叉更多的子进程,直到其中一些人死亡并且不会超额认购'K'限制。