[英]Question about fork()
这是我的功能:
void connection(int sock) // sock is a descriptor of socket
{
char buffer[MAX];
int n; // number of bytes read or write into a socket
int f;
f = fork();
if(write(sock,"HELLO\n", 5) < 0)
{
perror("Error: \n");
}
write(sock, "\n> ",3);
do {
memset(buffer,'0',MAX); //
n = read(sock,buffer,MAX -1 );
if (strncmp("get",buffer,3) == 0)
{
if(f == 0)
{
write(sock, "TOP:\n",4);
dup2(sock,1);
if(execl("/usr/bin/top","/usr/bin/top","-bn1",0) == -1)
write(sock, "ERROR",5);
}
else
{
waitpid(f, NULL, 0);
write(sock, "\n> ",3);
}
}
else if (strncmp("quit",buffer,4) == 0)
{
write(sock, "EXIT\n",4);
close(sock);
exit(0);
}
else
{
write(sock,"Wrong order\n", 12);
write(sock, "> ",2);
}
}
while(n);
}
此功能负责客户端和服务器之间的信息交换。 服务器应发送“ top”操作的结果。
此功能是TCP服务器程序的一部分。
当客户端在telnet帮助下与服务器连接时,他会看到:
> Hello
> //(and here I can write "get", to see top results)
在调用“ get”之后,我想再次看到“>”,所以我输入了:else
{
waitpid(f, NULL, 0);
write(sock, "\n> ",3);
}
但是我看不到“>”。 只有在telnet中写其他东西时,我才能看到它。 我应该将哪些子进程放入fork中,以调用父进程?
问候。
1) memset(buffer,'0',MAX);
将ASCII字符“ 0”写入缓冲区中的所有字节。 因此,不能保证您读取的字符串以null终止。
2)您的“命令行”处理方式无法正确处理封闭的套接字。 它退出do...while
循环,从connection()
返回……这可能不是您想要的。 您可能希望它执行与“退出”命令相同的操作。 “退出”命令的作用应该break;
而不是exit(0);
,然后exit(0);
应该放在while(n);
。
3)在fork()
之后,子进程和父进程将打开相同的文件。 每个进程都应关闭将不再使用的文件。 至少,这意味着父级(f!= 0)需要关闭sock
因为它现在是子级的属性。 同样,服务器(实际上是侦听器)进程应该在生成子进程之后返回到侦听更多连接。 为此,请将其放在f = fork()
行之后:
if(f != 0) // Or just 'if(f)' if your coding standards allow it.
{ // Parent continues here
close(sock);
return; // Or 'return f;' if you want to save the child's process ID for later.
}
// Child starts here
如果父进程打开了子进程不应该使用的文件,则应在此if(f != 0)
块之后立即关闭它们。
4)不能保证对read()
的调用只会使您得到一行,除非正在执行行缓冲(也许是您的终端?)。
5)您应该在do...while
循环内do...while
read()
之前立即写出提示。
6)当您执行execl()
,您当前的进程将消失,并且无法恢复。 我建议您研究一下popen()
命令集,并改用它们。
父级和子级都将HELLO发送到套接字。 并且都从套接字读取。 这是一个奇怪的行为。
如果要打开一个单独的进程来管理连接,则应像现在一样从头开始,并立即使用“ if(f == 0)”将父进程和子进程分开。 此后,如果我正确理解了您的意图,则孩子应发送HELLO等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.