Chinaunix

标题: fork与socket的问题 [打印本页]

作者: leiyu    时间: 2007-09-26 11:23
标题: fork与socket的问题
#include <iostream.h>
#include <netinet/in.h>
#include<arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
int main()
{
       pid_t pid;
        int iSocket,iReturn;
        struct sockaddr_in seraddr;
        int nbytes;
        char sendbuf[1024];
        char recvbuf[2048];

        seraddr.sin_port = htons(10001);
        seraddr.sin_family = AF_INET;
        seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
        iSocket = socket(AF_INET,SOCK_STREAM,0);
        if(iSocket < 0)
        {
                perror("create socket error:");
                return -1;
        }
        if   ((pid   =   fork   ())   >   0)
        {
                sleep(20);      
                cout<<"parent iSocket="<<iSocket<<endl;
           if(connect(iSocket,(struct sockaddr *)&seraddr, (int)sizeof(struct sockaddr_in)) < 0)
           {
                   perror("parent connect server error:");
                   return -1;
           }
                close(iSocket);
                exit(0);
        }//exit   (0);
        else
        {
          cout<<"parent iSocket="<<iSocket<<endl;  
         if(connect(iSocket,(struct sockaddr *)&seraddr, (int)sizeof(struct sockaddr_in)) < 0)
              {
                 perror("child connect server error:");
            return -1;
               }
               close(iSocket);
        exit(0);        
        }
}
hp unix 下结果是parent connect server error:: Socket is already connected
fork子进程复制父进程的资源,为什么子进程close(socket)后,父进程还是连接状态,请大家帮忙分析下
作者: 思一克    时间: 2007-09-26 11:51
本来就是如此。fork后,2个进程各自独立了。
fork子进程复制父进程的资源,为什么子进程close(socket)后,父进程还是连接状态,请大家帮忙分析下
作者: flw2    时间: 2007-09-26 12:15
close只是关闭描述符,如果只有这一个描述符引用socket才会断开连接
作者: leiyu    时间: 2007-09-26 12:57
flw2:
close需要发送fin消息包的,不是只是关闭描述符吧
作者: ddvv    时间: 2007-09-26 13:00
父进程和子进程的iSocket都指向文件表中的同一个项目,该文件被标记为打开了两次,因此子进程进行了连接以后,虽然过后把它关了,但是父进程的iSocket依然有效,该文件的打开次数还不为0,所以就会出现这样的错误吧。不知道是不是这样
作者: ddvv    时间: 2007-09-26 13:03
原帖由 leiyu 于 2007-9-26 12:57 发表
flw2:
close需要发送fin消息包的,不是只是关闭描述符吧


如果是引用次数为0的时候才发送fin包呢?
作者: lgkingdom    时间: 2007-09-26 13:19
haha,又学了很多东西
作者: lgkingdom    时间: 2007-09-26 13:20
发现个问题,就是父fork子后反映巨慢,即使去掉子的connect也一样
作者: zwylinux    时间: 2007-09-26 13:21
原帖由 ddvv 于 2007-9-26 13:03 发表


如果是引用次数为0的时候才发送fin包呢?

是的,如果用shutdown代替的话就不管三七二十把文件描述符给关了,呵呵
作者: ddvv    时间: 2007-09-26 13:25
恩,相关的内容可以看一下APUE和Unix网络编程相关章节
作者: leiyu    时间: 2007-09-26 13:26
标题: 回复 #5 ddvv 的帖子
该标记打开了两次,怎么能这样呢,父进程并没有打开,只是在sleep,而且子进程复制父进程相对独立,难道fork时,系统会对资源加访问控制?
作者: JohnBull    时间: 2007-09-26 13:27
原帖由 zwylinux 于 2007-9-26 13:21 发表

是的,如果用shutdown代替的话就不管三七二十把文件描述符给关了,呵呵


非也。
发送FIN并不意味着要关闭连接。

man 2 shutdown
作者: zwylinux    时间: 2007-09-26 13:33
用shutdown引起发送fin当然不一定会关闭连接,但至少会关闭某一个方向的连接吧
作者: ddvv    时间: 2007-09-26 13:33
原帖由 leiyu 于 2007-9-26 13:26 发表
该标记打开了两次,怎么能这样呢,父进程并没有打开,只是在sleep,而且子进程复制父进程相对独立,难道fork时,系统会对资源加访问控制?


呵呵,也不能说打开了两次吧,应该说有2个引用
作者: ddvv    时间: 2007-09-26 13:34
fin只是说没有数据要发送了吧,但是还是可以读的~
作者: leiyu    时间: 2007-09-26 13:40
标题: 回复 #14 ddvv 的帖子
子进程close时,父进程在sleep还没有引用此资源,那引用应该是0吧,socket应该关闭,如果子进程关闭了,那个错误提示又是如何得出的?
作者: leiyu    时间: 2007-09-26 13:45
标题: 回复 #14 ddvv 的帖子
哦,close是不是有点像semphone
作者: lgkingdom    时间: 2007-09-26 13:57
引用是在创建时就有了,fork后,子进程又引用了一次,但是子进程close后为什么父进程还提示以连接就不知道了,高手说说吧
作者: flw2    时间: 2007-09-26 14:18
原帖由 lgkingdom 于 2007-9-26 13:57 发表
引用是在创建时就有了,fork后,子进程又引用了一次,但是子进程close后为什么父进程还提示以连接就不知道了,高手说说吧


man 2 close

close()  closes  a  file descriptor, so that it no longer refers to any file and
       may be reused.  ....................

If fd is the last copy of a particular file descriptor the resources  associated
       with  it are freed;
作者: ddvv    时间: 2007-09-26 15:35
哈哈,man一下就出来了~




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2