什麼是通用套接字,它與網路設備有什麼關係?
我試圖了解網路驅動程序在 Linux 下是如何工作的。此問答表明 Linux 中的網路設備不是由設備文件表示的。它指出網路驅動程序與
sockets
.例如,這參考瞭如何通過
ioctl
呼叫來設置網路設備。ioctl
但是需要一個文件描述符,因為沒有用於網路驅動程序的設備文件,唯一可以傳遞的文件描述符是來自套接字的文件描述符。這讓我想到了問題的重點。到目前為止,網路介面似乎是物理網卡的軟體表示,實際上是套接字的劣等對象。
- 但是這個抽象意義上的套接字是什麼,它只是支持推送通知的設備文件的另一個名稱嗎?我根據使用者空間應用程序綁定到網路介面上的地址:埠對的連接點來理解 TCP 套接字。我不明白套接字是設置網路介面的先決條件。
- Linux 上的網路介面(如
eth0
列出的ifconfig
)是否可以在沒有套接字的情況下存在?- 是否
ifconfig
或某些網路管理器守護程序保持打開套接字以允許我們設置網路介面選項?
讓我們快速回顧一下設備文件:在 Linux 中,應用程序通過文件描述符將 rad 和寫入操作傳遞給核心。這對文件很有效,事實證明,相同的 API 可以用於產生和消費字元流的字元設備,以及在隨機訪問地址讀取和寫入固定大小塊的****塊設備,只需假裝這些也是文件。
但是需要一種方法來配置這些設備(設置波特率等),為此,發明了ioctl呼叫。它只是將特定於設備的資料結構和用於核心的 I/O 控制類型傳遞給核心,並以相同的資料結構返回結果,因此它是一個非常通用的可擴展 API,可以用於很多事情.
現在,網路運營如何適應?一個典型的網路伺服器應用程序想要綁定到某個網路地址,監聽某個埠(例如 HTTP 為 80,ssh 為 22),如果客戶端連接,它想向該客戶端發送數據並從該客戶端*接收數據。*和客戶端的雙重操作。
如何將其與文件操作相適應並不明顯(儘管可以做到,參見計劃 9),這就是 UNIX 設計者發明新 API:sockets的原因。您可以在第 2 節手冊頁中找到有關
socket
、bind
、listen
、connect
和send
的詳細資訊recv
。請注意,雖然它與文件 I/O API 不同,但該socket
呼叫仍然返回一個文件描述符。網上有很多關於如何使用套接字的教程,google了一下。到目前為止,這都是純 UNIX,在發明套接字時沒有人談論網路介面。而且因為這個 API 實在太老了,它是為 Internet 協議之外的各種網路協議定義的(查看
AF_*
常量),儘管在 Linux 中只支持其中的一小部分。但是隨著電腦開始獲得多個網卡,需要對此進行一些抽象。在 Linux 中,這就是網路介面(NI)。它不僅用於硬體,還用於各種隧道、作為 OpenVPN 等隧道伺服器的使用者應用程序端點等。如上所述,套接字 API 不基於(特殊)文件並且獨立於文件系統。同樣,網路介面也不會出現在文件系統中。但是,NI 在文件系統(
/proc
以及/sys
其他網路可調參數)中可用。NI 是網路數據包進入和離開核心的端點的簡單核心抽象。另一方面,套接字用於與應用程序通信數據包。處理數據包時不需要涉及任何套接字。例如,啟用轉發時,數據包可能會在一個 NI 上進入並在另一個 NI 上離開。從這個意義上說,套接字和網路介面是完全獨立的。
但是必須有一種配置 NI 的方法,就像您需要一種配置塊設備和字元設備的方法一樣。而且由於套接字已經返回了一個文件描述符,因此只允許
ioctl
該文件描述符上的一個有點合乎邏輯。那是您連結的網路設備介面**。**還有很多其他類似的系統呼叫濫用,例如數據包過濾、數據包擷取等。
所有這些都是一塊接一塊的,在很多地方並不是特別合乎邏輯。如果它是一次性設計出來的,那麼人們可能會製作一個更加正交的 API。