close()和exit()调用

时间:2018-01-21 16:32:24

标签: c linux sockets networking tcp

pid_t pid;
int listenfd, connfd;
listenfd = socket(...);
bind(listenfd, ...);
listen(listenfd, 5);
connfd = accept(listenfd, ...);
if ((pid = fork()) == 0){
    close(listenfd);
    doit(connfd); /* processes the clients request*/
    close(connfd);
    exit(0);
}
wait(...)

调用wait函数后,我将拥有多少个TCP连接? 我认为它应该是0,但我不知道close()函数的作用。它是关闭每个进程还是只关闭一个进程(子进程或父进程)? 谢谢!

1 个答案:

答案 0 :(得分:1)

accept()的一次成功通话设置了一个连接。对于阻止侦听套接字,它将返回已连接套接字 * 1

分叉后,服务器使用其连接的套接字connfd的副本引用此一个连接。

然后,进程分叉和第二个进程保存connfd的副本。

这两个套接字描述符都引用相同的连接。

监听套接字永远不会真正引用连接。它只是一种传感器,列出了传入的请求。)

* 1 对于解除阻塞侦听套接字,在时序方面有些不同。在这种情况下,可能是accept()返回时连接设置未完全完成。

所以回答你的问题:

  

调用wait函数后我将拥有多少个TCP连接?

在调用wait()之后,只有一个引用建立的连接accept()的两个套接字描述符的副本已经close() d。另一个仍“保持”连接。

假设代码没有在任何地方调用shutdown()或者使任何套接字解锁,稍微调整一下代码,模式通常如下所示:

listenfd = socket(...);
bind(listenfd, ...);
listen(listenfd, 5);

connfd = accept(listenfd, ...);

/* Connection is up. */

if ((pid = fork()) == 0)
{
  /* Connected child process here */

  close(listenfd); /* Close the connected processes's listening listenfd 
                      as it never uses it. */
  doit(connfd); /* Processes the clients request. */

  close(connfd);

  exit(0);
}

/* Listening parent process here */

close(connfd) /* Close the accepting process' connected connfd 
                 as it never uses it. */
wait(...)

/* Definitely no connection here any more */