摘要:在使用linux下的c语言进行网络编程实现C/S时一直好奇,server端的子进程和父进程的listenfd和connfd在数值上都是相同的,在server端程序运行时是怎么区分的。而从百度上也没有什么详细的答案,闲来无事便开始玩玩。

核心代码

while (1)

    {
        if ((connfd = accept(listenfd, (struct sockaddr*) & client, (socklen_t*)&len)) == -1)

        {
            perror("accept() error\n");
            exit(1);
        }

        if ((pid = fork()) > 0)

        {
                close(connfd);
            continue;
        }

        else if (pid == 0)

        {

            printf("the jin cheng is %d,%d\n",listenfd,connfd);
            close(listenfd);
            process_cli(connfd, client);
            exit(0);
        }

        else

        {
            printf("fork() error\n");
            exit(0);

        }
    }

connfd和listenfd在父进程运行中没用任何改变,每一个子进程的connfd和listenfd都一样。这样会不会造成干扰?每一个子进程又是如何区分?

研究过程

查看tcp连接
netstat -anot
QQ截图20200122162143.jpg

打印出进程号和父子进程关系
ps axo pid,ppid,comm | grep zuoye
QQ截图20200122162537.jpg

查看端口1234所关联的文件
lsof -i tcp:1234
QQ截图20200122162736.jpg

后面四个文件为socket文件,代表已连接的socket套接字描述符。

交互过程如下:

QQ截图20200122160524.jpg

查看父进程pid=40829所关联的文件:

QQ截图20200122163635.jpg

查看父进程的子进程pid=40831
QQ截图20200122164004.jpg

在/proc/40831/fd下查看pid=40831的文件描述符

QQ截图20200122164219.jpg

在/proc/41153/fd下查看pid=41153的文件描述符
QQ截图20200122164641.jpg

这个时候明白了为啥connfd和listenfd相同,为啥不会相互影响。一个父进程会fork几个子进程,这几个子进程是互相独立的,一个子进程的环境是/proc/40831,一个子进程的环境是/proc/41153,而fd下面有一个名字叫做4的状态为已连接的socket套接字描述符。