Socket与系统调用深度分析

Posted yusi007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Socket与系统调用深度分析相关的知识,希望对你有一定的参考价值。

1、Socket API编程接口

  网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。

  socket系统调用的定义在net/socket.c中,如下:

 1 int __sys_socket(int family, int type, int protocol)
 2 {
 3     int retval;
 4     struct socket *sock;
 5     int flags;
 6 
 7     /* Check the SOCK_* constants for consistency.  */
 8     BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
 9     BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
10     BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
11     BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);
12 
13     flags = type & ~SOCK_TYPE_MASK;
14     if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
15         return -EINVAL;
16     type &= SOCK_TYPE_MASK;
17 
18     if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
19         flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
20 
21     retval = sock_create(family, type, protocol, &sock);
22     if (retval < 0)
23         return retval;
24 
25     return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
26 }
27 
28 SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
29 {
30     return __sys_socket(family, type, protocol);
31 }

  socket的内核实现大致调用流程如下:

    技术图片

2、系统调用机制

  一个Linux系统分为三个层次:用户层、核心层、硬件层。其中系统调用是用户层与核心层的边界,通过系统调用进程可由用户层转入核心层,在核心层完成指定服务请求后,再返回用户层。

  系统调用接口看起来和C程序中的普通函数调用很相似,它们通常是通过库把这些函数调用映射成进入操作系统所需要的原语。这些操作原语只是提供一个基本功能集,而通过库对这些操作的引用和封装,可以形成丰富而且强大的系统调用库。这里体现了机制与策略相分离的编程思想——系统调用只是提供访问核心的基本机制,而策略是通过系统调用库来体现。

  每个进程都有自己的地址空间,进程的地址空间分为两部分:用户空间和内核空间。在用户态,只能访问进程的用户空间;在内核态,可以访问进程的全部地址空间。地址空间中的地址是逻辑地址,通过系统段面式的管理机制,访问的实际内存要做二级地址转换,即:逻辑地址-->线性地址-->物理地址。

  系统调用在使用时和一般的函数调用很相似,但是二者是有本质性区别的,函数调用不能引起从用户态到核心态的转换,而正如前面提到的,系统调用需要有一个状态转换。在每种平台上,都有特定的指令可以使当前线程由用户态转换为核心态,这种指令称作操作系统陷入(operatingsystemtrap)。线程通过执行陷入指令,便可以在核心态运行系统调用代码。在Linux中是通过软中断来实现这种陷入的,在x86平台上,中断指令是int0x80。也就是说在Linux中,系统调用的接口是一个中断处理函数。

3、Linux Socket api对应的系统调用如何被内核处理的

  我们通过gdb调试来查看具体程序中socket api对应的系统调用如何被处理的,我们先打开一个menuos界面,然后重新打开一个窗口打开gdb调试。并设断点:

gdb
file linux-5.0.1/vmlinux
target remote:1234
b __sys_socket

技术图片

然后对socket api系统调用函数设置断点,查看replyhi和hello函数中对其的调用技术图片

以上是关于Socket与系统调用深度分析的主要内容,如果未能解决你的问题,请参考以下文章

Socket与系统调用深度分析

Socket与系统调用深度分析

Socket与系统调用深度分析

Socket系统调用Socket与系统调用深度分析

Socket与系统调用深度分析

Socket与系统调用深度分析