天天看點

再談linux中為何沒有網卡裝置檔案--深層次原因

這個問題其實沒有什麼意思,知道了問題的答案能表明一個人技術水準有多高嗎?不能!這個問題有答案以及有意義嗎?答案都是沒有!那我還為何一直對這個問題死死揪住不放?這類問題可以提高一個人的素質以及了解一段關于網絡和unix的曆史,正是因為這些都很有趣,才如此值得關注。

在unix中,一切io相關的實體都被抽象成了檔案,之是以抽象成檔案第一是為了接口統一,第二是為了操作統一,第三是為了政策隐藏,比如這樣可以向使用者屏蔽掉具體裝置的細節或者具體檔案系統的細節,檔案抽象有塊抽象和字元抽象,對于塊檔案,你隻需要知道它可以随機讀寫就可以完成大部分的工作而不用關注底層具體的檔案系統,比如ext3,ntfs,jfs之類,對于字元裝置檔案,你隻需要知道他們是串行讀寫就可以了,而不必關心滑鼠的電路安排,列印機的内部機制等等,但是對于網卡,我們看看它是字元裝置還是塊裝置。如果它是塊裝置,那麼它能随機讀寫嗎?看看網卡的特性,它的另一端是另一個世界,它更像是一個管道,它更像是一個字元裝置,因為對一個管道進行随機讀寫是沒有意義的,那麼它是一個字元裝置嗎?要知道網絡協定多種多樣,計算機僅僅負責按照協定加工資料而不對協定本身做任何限制,是以如果将網卡作為字元裝置,那麼為了支援衆多協定以及為了在傳輸之前綁定一個協定,就必須頻繁調用ioctl之類的系統調用,這樣使用者就必須知道網卡這個裝置的更多的細節,否則使用者怎麼去ioctl這塊網卡,這顯然違背了unix檔案抽象的初衷,另外怎麼去同步這個裝置,比如多個程序同時需要打開這個裝置傳輸網絡資料,怎麼能保證它們可以用最高的效率複用這個網卡,這個同步工作應該由誰來做,系統還是使用者,如果由系統來做,傳統的檔案同步接口将在網卡裝置檔案失效,如果由使用者來完成,那麼使用者必須對網卡像驅動工程師一樣熟悉,一個使用者弄壞網卡的一個寄存器就會導緻整個網卡down掉...第三,如何支援網絡協定,難道讓使用者自己進行協定封裝然後write到網卡嗎?協定棧在這種情況下必須在使用者空間實作,如此一來,效率和健壯性呢?安全性呢?協定棧顯然受不到作業系統的核心空間特權級别的保護待遇,這違背了安全原則。綜上,網卡不能被抽象成裝置檔案,因為将之抽象之後得不到任何好處。

bsd套接字解決上檔案抽象問題,為了使用檔案接口,bsd套接字仍然使用檔案接口,下層直接和核心空間的協定棧接口,所有的同步以及協定規程都在協定棧完成,裝置複用由協定棧和裝置驅動共同完成,這個bsd套接字抽象簡直就是一件藝術品,人們又回到了一切皆檔案的美麗又和諧的世界,bsd套接字通過一個新的系統調用socket來代替open進而可以實作諸如協定綁定之類的和open語義不相關的操作,另外connect和accept也實作了自己的語義。當初為何不将網絡裝置作為檔案抽象呢?實際上有一個本質的原因,那就是unix根本就不把網絡通信作為IO,而是作為IPC,實際上unix從一開始就将網絡當成了計算機,否則它也不會将網絡通信作為IPC,程序間通信可以在同一台機器,也可以在不同的機器,實際上機器并不是界限。unix将網絡通信當成了像共享記憶體,信号量之類的IPC機制了,隻不過後者是同一台機器内部的機制,不需要硬體,而網絡通過需要硬體實作,硬體就是網卡之類的裝置,unix僅僅将網絡設别作為了實作IPC的手段罷了。

 本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1273341

繼續閱讀