Linux中本機和本機Socket通信會走網卡嗎?
Linux中本機和本機通信,例如一個程序請求本機上的一個socket服務,或者請求本機上的一個http介面。請求會經過網卡,走網路嗎?是否linux內核有相關優化呢?
網路層/路由層決定怎麼走。然後就沒有介質訪問控制層/數據鏈路層/物理層什麼事了。
這個其實無需做實驗,把網路協議層的知識複習一遍就知道了。無論是七層協議模型還是四層協議模型都可以清楚的解釋這個事情。先說結論:不走網卡,不走物理設備,但是走虛擬設備,loopback device環回.
本機的報文的路徑是這樣的:
應用層-&> socket介面 -&> 傳輸層(tcp/udp報文) -&> 網路層 -&> back to 傳輸層 -&> backto socket介面 -.&> 傳回應用程序
在網路層,會在路由表查詢路由,路由表(軟體路由,真正的轉發需要依靠硬體路由,這裡路由表包括快速轉發表和FIB表)初始化時會保存主機路由(host route,or 環迴路由), 查詢(先匹配mask,再匹配ip,localhost路由在路由表最頂端,最優先查到)後發現不用轉發就不用走中斷,不用發送給鏈接層了,不用發送給網路設備(網卡)。像網卡發送接收報文一樣,走相同的接收流程,只不過net device是loopback device,最後發送回應用程序。這一套流程當然和轉發和接收外網報文一樣,都要經過內核協議棧的處理,不同的是本機地址不用掛net device.
我寫一個測試程序,結論是:不需要走網卡。
我生成了一個5G的大文件。同時傳輸的過程中,我把網卡拔掉,最後數據傳輸完畢。
不過這是一個很傻逼的行為,因為直接把網卡拔掉就可以測試。
至於原因 @pansz已經提到了。 雖然我行為是傻逼了點,不過寫這個程序的過程中還是收穫不少呢,因為剛學網路編程,多挖幾個坑還自己還是有好處的。
代碼如下:生成文件的代碼:
#define SIZE 5000000
#define OPEN_MODE 00777
int main(int argc,char **argv){
srand(time(NULL));
int fd=open("output.txt",O_APPEND|O_RDWR);
int n=0;
char buf[1024]={0};
for(int i=0;i&