Chinaunix首页 | 论坛 | 博客
  • 博客访问: 147313
  • 博文数量: 32
  • 博客积分: 2050
  • 博客等级: 大尉
  • 技术积分: 335
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-10 09:43
文章分类

全部博文(32)

文章存档

2012年(1)

2011年(1)

2009年(1)

2008年(5)

2007年(22)

2006年(2)

我的朋友

分类: LINUX

2008-11-28 14:39:46


Figure 4.13 Outline for typical concurrent server.
pid_t pid;
int   listenfd,  connfd;

listenfd = Socket( ... );

    /* fill in sockaddr_in{} with server's well-known port */
Bind(listenfd, ... );
Listen(listenfd, LISTENQ);

for ( ; ; ) {
    connfd = Accept (listenfd, ... );    /* probably blocks */

    if( (pid = Fork()) == 0) {
       Close(listenfd);    /* child closes listening socket */
       doit(connfd);       /* process the request */
       Close(connfd);      /* done with this client */
       exit(0);            /* child terminates */
    }

    Close(connfd);         /* parent closes connected socket */
}

   We said in Section 2.6 that calling close on a TCP socket causes a FIN to be sent, followed by the normal TCP connection termination sequence. Why doesn't the close of connfd in Figure 4.13 by the parent terminate its connection with the client? To understand what's happening, we must understand that every file or socket has a reference count. The reference count is maintained in the file table entry (pp. 57–60 of APUE). This is a count of the number of descriptors that are currently open that refer to this file or socket. In Figure 4.13 , after socket returns, the file table entry associated with listenfd has a reference count of 1. After accept returns, the file table entry associated with connfd has a reference count of 1. But, after fork returns, both descriptors are shared (i.e., duplicated) between the parent and child, so the file table entries associated with both sockets now have a reference count of 2. Therefore, when the parent closes connfd, it just decrements the reference count from 2 to 1 and that is all. The actual cleanup and de-allocation of the socket does not happen until the reference count reaches 0. This will occur at some time later when the child closes connfd.
 
    这是stevens关于多进程迭代服务器的一个说明,fork之后内核中关于这个connfd的引用计数会增加,所以父进程关闭connfd,不会导致发送FIN报文。引用计数为1时,在该connfd上执行的close操作才会引发FIN的发送。
 
 
 
阅读(878) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~