关于 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 子进程中放入什么来调用我的父进程?
问候。
this is my function:
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);
}
This function is responsible for information exchange among client and server. The server should sends the results of "top" action.
This function is a part of TCP server program.
When client connect with server with telnet help, he see:
> Hello
> //(and here I can write "get", to see top results)
I' d like to see ">" again, after call "get", so I' ve put:
else
{
waitpid(f, NULL, 0);
write(sock, "\n> ",3);
}
But I do not see my ">". I can see it, only when I write in telnet something else. What should I put in my child process in fork, to invoke my parent process?
Regards.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
1)
memset(buffer,'0',MAX);
将 ASCII 字符“0”写入缓冲区中的所有字节。因此,不能保证您读取的字符串以 null 结尾。2)您的“命令行”处理不能正确处理关闭的套接字。它退出
do...while
循环,从connection()
返回...这可能不是您想要的。您可能希望它执行与“退出”命令相同的操作。 “quit”命令 cose 应该break;
而不是exit(0);
,并且exit(0);
应放在while(n);。3) 子进程和父进程将在
fork()
之后打开相同的文件。每个进程都应该关闭不再使用的文件。至少,这意味着父级 (f != 0) 需要关闭sock
因为它现在是子级的属性。此外,服务器(实际上是侦听器)进程应该在生成子进程后返回侦听更多连接。为此,请将其放在f = fork()
行之后:如果父进程打开了子进程不应弄乱的文件,则应在该
if(f != 0)
块。4) 不能保证调用
read()
会得到一行,除非有东西正在执行行缓冲(也许是您的终端?)。5) 您应该在执行
do...while
循环内的read()
之前写出提示。6) 当您
execl()
时,您当前的进程就会消失,并且无法返回。我建议您研究popen()
命令集并使用它们。1)
memset(buffer,'0',MAX);
writes the ASCII character '0' to all bytes in your buffer. Therefore, there is no guarantee that the string you read in null-terminated.2) Your "command line" handling doesn't handle a closed socket right. It exits the
do...while
loop, returning fromconnection()
... which is probably not what you want. You probably want it to do the same thing as a "quit" command. The "quit" command cose shouldbreak;
instead ofexit(0);
, and theexit(0);
should be put after thewhile(n);
.3) The child process and parent process will, right after
fork()
, have the same files open. Each process should close the files it will no longer use. At the very least, this means the parent (f != 0) needs to closesock
because it is now the property of the child. Also, the server (actually, listener) process should go back to listening for more connections after spawning the child process. To do this, put this after thef = fork()
line:If the parent process has files open that the child should not mess with, they should be closed right after this
if(f != 0)
block.4) There's no guarantee that a call to
read()
will get you a single line, unless something is performing line buffering (maybe your terminal?).5) You should write your prompt out right before you do the
read()
, inside yourdo...while
loop.6) When you
execl()
, your current process goes away, and there's no way to get back. I recommend you investigate thepopen()
set of commands and use them instead.父级和子级都向套接字发送 HELLO。两者都从套接字读取。这是一个奇怪的行为。
如果你想要打开一个单独的进程来管理连接,你应该像现在一样从一开始就fork,并立即用“if(f==0)”分隔父进程和子进程。之后,如果我正确理解了你的意图,孩子应该发送 HELLO 等。
Both parent and child send HELLO to the socket. And both read from the socket. That's a strange behavior.
If what you want is to open a separate process to manage the connection, you should fork at the beginning as you now do, and immediately separate the parent and child processes with the 'if (f==0)'. After that the child should send the HELLO, etc., if I correctly understood your intention.