我正在尝试使用BlueZ HCI函数:

int hci_open_dev(int dev_id) {...}

在内部尝试创建这样的套接字:
socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);

我试图了解socket()的Linux内核代码,但感到迷茫。

我想知道为给定域(AF_BLUETOOTH),数据传输类型(SOCK_RAW)和协议(protocol)(BTPROTO_HCI)创建套接字的确切含义。

手册页仅说明它接受了这些参数,创建了一个套接字并返回了一个设备描述符。

但是id喜欢了解到底发生了什么以及创建套接字所涉及的确切内核步骤。

最佳答案

这是一个非常广泛的描述(希望有助于理解主要方案的希望)。
内核开发人员可能会感到恐惧...

套接字是用于许多不同通信方式的通用抽象接口(interface)。
它提供了许多通用操作,例如关闭,发送/接收数据,设置/检索选项,这些操作几乎可以在任何类型的套接字上使用。

创建套接字意味着指定此通信方式的确切属性。
有点像实现接口(interface)的具体类型的实例化。

这些属性首先按协议(protocol)系列进行组织。这是socket()调用的第一个参数。
例如:

  • PF_INET用于依赖IPv4的通信
  • PF_INET6用于依赖IPv6的通信
  • PF_LOCAL用于系统内部的进程间通信(管道种类),
  • PF_NETLINK用于与OS内核
  • 进行通信
  • PF_PACKET用于与网络接口(interface)
  • 直接通信
  • ...(存在很多)

  • 一旦选择了协议(protocol)系列,则必须指定该系列提供的协议(protocol)中要使用的协议(protocol)。这是socket()调用的第二个参数。
    例如:
  • SOCK_DGRAM用于IPv4或IPv6上的UDP,或PF_LOCAL中的不同消息,
  • SOCK_STREAM用于IPv4或IPv6上的TCP,或PF_LOCAL中的连续字节流,
  • SOCK_RAW,直接访问是该族中的原始基础协议(protocol)(如果有)(例如,IPv4或IPv6),
  • ...(每个家庭可以提供很多)

  • 某些协议(protocol)可以接受某些变体或某些限制。这是socket()调用的第三个参数。
    通常,0就足够了,但是例如,我们可以找到:
  • PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)捕获在网络接口(interface)
  • 上接收到的任何类型的网络数据包
  • PF_PACKET,SOCK_RAW,htons(ETH_P_ARP)仅捕获ARP帧

  • 当我们要求使用这三个参数创建套接字时,操作系统将创建与该套接字句柄关联的内部资源。
    当然,该资源的确切结构取决于所选择的族/协议(protocol)/变体,并且它与特定于它的内核回调相关联。
    每次(通过系统调用)在此套接字上调用操作时,都会调用特定的回调。

    关于c - socket()函数的内部机制是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57152408/

    10-15 15:01