socket编程中父子进程、兄弟进程的端口问题

来源:互联网 发布:知聊下载 编辑:程序博客网 时间:2024/06/06 01:03
最近在linux下弄一些socket方面的东西,涉及到父子进程、兄弟进程间的端口、socket句柄的问题,主要问题集中在两个方面:

1、假如父进程监听A端口,那么在client端来连接,并fork子进程,那么子进程通过那个端口与client交换数据呢?
通过实验显示,还是端口A。为什么?端口复用技术!那么,实验是怎么做的呢?其实很简单,server端启动,在fork出子进程时保证每个子进程的连接保持(可以通过sleep让其休息一会),此时,通过 “netstat -pan | grep A” 就可以看到有关端口A的一些信息,可以发现有子进程通过A与对应的client的连接(establish),同时父进程在端口A进行Listen!所以,我们可以知道,端口A时父子进程共用的,想起以前的操作系统,这不就是端口复用么。


2、socket句柄的问题。
这是一个困扰我多是的问题,问题的形式很简单,下面给出伪代码:
code begin:
socket();
bind();
listen();
while(true)
 {
       clientFd=accept();

      if(fork()==0)
           do_child_things();
     else
           close(clientFd);
}
code end.

现在问题来了,记父进程为F,子进程依次为C1,C2,C3...现在client1,client2,client3同时连接,那么,在client1、client2、client3中对应的子进程中,clientFd是一样的(这点不需怀疑,我已经实验过N多次了)。

现在问题来了,还记得父子进程中关于普通文件句柄的一些事么?

是的,父子进程中的文件句柄是一样的,而且在子进程中对文件句柄进行操作会效果和在父进程的效果是一样的!假若socket句柄也是一样的岂不是没的完了!因为这样一来就全乱了套了么。

事实不是的,我已实验证明。那么为什么呢?其实通过句柄操作一个文件或者一个管道时,这个被操作的对象的确定是值得思考的。

因为我们确定的访问对象是由一个暂且称之为进程环境的东西规定的,我们所说的普通意思的文件句柄是相对一个相同的文件系统中一个文件所说的,这个文件在这个文件系统是唯一的,所以父子进程指向的是同一个地方,但是我们的socket句柄的进程环境就不同与我们的当地文件系统,这是由子进程的端口以及对应的连接的client的端口确定的,而每个client对应的端口信息是不同的,就是这个确定的因素已经超出了父进程所在的这个当地系统定义环境,因此,大家相安无事!

就好比是你是A村的阿牛,如果你们村只有你一个阿牛,那么在你们村里叫阿牛一定就是叫你,这个村子就是父进程所在的这个local system,无论父子进程谁叫阿牛,都是在叫你。但是假如现在有B村的阿牛和C存的阿牛来了你们村上的亲戚家玩,现在他们的亲戚要给红包了,会给错么?你也知道不会,为什么?因为知道这个是B村的,那个是C村的,亲戚的红包相对应的就给对应的阿牛!这个亲戚就是子进程,不同的子进程和自己对应的client端确定的socket就当然不同,尽管他们是一样的——在数值上!

0 0