Socket的实现(Linux内核部分)

在Linux内核中,提供了一个统一的接口sys_socketcall,用于处理socket所有动作.

下面就是它的代码片段:

   1. asmlinkage long sys_socketcall(int call, unsigned long __user *args) 
   2. { 
   3.     unsigned long a[6]; 
   4.     unsigned long a0, a1; 
   5.     int err; 
   6. .......................................... 
   7.  
   8.     a0 = a[0]; 
   9.     a1 = a[1]; 
  10.  
  11.     switch (call) { 
  12.     case SYS_SOCKET: 
  13.         err = sys_socket(a0, a1, a[2]); 
  14.         break; 
  15.     case SYS_BIND: 
  16.         err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]); 
  17.         break; 
  18.     case SYS_CONNECT: 
  19.         err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]); 
  20.         break; 
  21.     case SYS_LISTEN: 
  22.         err = sys_listen(a0, a1); 
  23.         break; 
  24.     case SYS_ACCEPT: 
  25.         err = 
  26.             do_accept(a0, (struct sockaddr __user *)a1, 
  27.                   (int __user *)a[2], 0); 
  28.         break; 
  29.     case SYS_GETSOCKNAME: 
  30.         err = 
  31.             sys_getsockname(a0, (struct sockaddr __user *)a1, 
  32.                     (int __user *)a[2]); 
  33.         break; 
  34. ..................................... 
  35.     return err; 
  36. } 

可以看到代码比较简单,就是通过传递进来的call类型,来调用相应的socket相关的函数.

这里你可能注意到了,那就是一般文件句柄相关的操作,比如write,read,aio,poll这些并没有看到(也就是 file_operations).这是因为socket上面其实还有一层vfs层,内核把socket当做一个文件系统来处理,并实现了相应的vfs方法.因此下面我们先来了解下vfs.然后会描述下进程如何通过vfs存取句柄.

vfs其实就相当于对下层的文件系统和上层应用之间的粘合层,它定义了文件系统需要实现的相关的操作,然后下层的文件系统只需要实现这些方法就可以了,也就是说在内核其他部分和上层应用看来,所有的文件系统没有任何区别.

下面的这张图就是从用户空间调用write的大体流程:

Socket的实现(Linux内核部分)

相关推荐