2007年10月22日星期一

销毁一个套接字(一)

要使我们的工作得以顺利进行,我们必须把建立与销毁,注册与注销等配对的工作放在一起完成,才能使模块始终处于一个可使用的状态。所以,完成了套接字的创建,我们下一步紧接着面临的工作就是套接字的销毁。
在系统调用层,套接字也是一个文件描述符来表示,所以,关闭套接字跟关闭打开着的文件并没有区别,都是使用close(fd),但同样一个操作,在内核中却发生着很不一样的操作。
我们还需要从socket系统调用创建套接字讲起,当代表套接字的一个struct socket结构被完整创建出来以后,它被映射到一个文件描述符,并且系统把这个文件描述符返回给用户。现在,我们就需要简单了解这个映射过程是怎么样的。
因为我们的目标是重新建立一个INET域的代码,所以不想在关于文件系统的方面走太远,所以只进行简单介绍。我们首先要从系统获取一个未使用的文件描述 符,并创建一个struct file结构。同时,我们初始化这个struct file结构,整个初始化过程我们只需要关注其中两步:
sock->file = file;
file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
在这个file结构的f_op成员中,我们记录了能对该文件(因为,此时,socket提供一组跟普通文件完全一致的操作 socket_file_ops,所以,能够被看成是一个文件)进行的所有操作。其中,包括一个release操作,这在我们销毁一个套接字时非常有用。
最后,我们把文件描述符fd和结构file安装到进程的描述符中。进程的描述符中有一个file_struct结构成员,它是一个进程所拥有的打开的文件 的列表。其中有一个成员struct file **fd,我们使fd[fd] = file。这样,就完成了文件描述符到socket的映射,即我们通过current->files->fd[fd]能找到file,通过 sock->file也能找到file。其实,它们之间还有其它关系。
有了这层关系,我们在close(fd)时,便能通过fd轻松调用到socket_file_ops.release(...)函数,最终完成销毁套接字的工作,有关具体的销毁流程,下回分解。

没有评论: