关于fork()的问题

时间:2010-01-02 20:13:56

标签: c 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);
}

此功能负责客户端和服务器之间的信息交换。服务器应该发送“顶部”操作的结果。

此功能是TCP服务器程序的一部分。

当客户端使用telnet帮助与服务器连接时,他会看到:

> Hello
> //(and here I can write "get", to see top results)

我想看看“&gt;”再次,在致电“得到”之后,我放了:  其他

        {
        waitpid(f, NULL, 0);
        write(sock, "\n> ",3);
        }

但我没有看到我的“&gt;”。只有当我用telnet写别的东西时,我才能看到它。我应该在fork的子进程中放入什么来调用我的父进程?

问候。

2 个答案:

答案 0 :(得分:4)

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)您应该在read()循环内do...while之前写出提示。

6)当你execl()时,你当前的过程消失了,没有办法回来。我建议您调查popen()命令集并改为使用它们。

答案 1 :(得分:3)

父母和孩子都将HELLO发送到套接字。并且都从套接字读取。这是一种奇怪的行为。

如果你想要的是打开一个单独的进程来管理连接,你应该像现在一样在开头分叉,并立即用'if(f == 0)'分隔父进程和子进程。如果我正确理解你的意图,那么孩子应该发送HELLO等。