關於Socket程式設計中的位址組和協議組

2021-04-13 07:50:06 字數 1380 閱讀 8430

原文請參見

寫socket程式,恐怕都是從socket函式開始的。但是對這個函式卻很少深入**。在此我給出一些我的分析結果。

先看原型:  socket socket(int af,int type,int protocol);  //windows

int socket(int domain, int type, int protocol); //linux

除 了返回值不同外,第乙個引數還是不同的。我們注意到,windows下第乙個引數是af(address family),而linux下則是domain(protocol family)。而看引數的值,也有af_*和pf_*之別。那麼這兩者之間究竟有沒有區別呢?

位址族和協議族究竟是否為一碼事呢?很顯 然,他們應該含義是不同的。比如,internet協議族(v4)裡分tcp、udp等協議,但是他們統屬internet協議族(pf_inet)。而 對應的,他們的位址也是ipv4位址。所以其位址族為(af_inet)。但是無論看win下還是linux下的定義就會發現,所有的都是 (#define pf_inet af_inet),也就是說,位址族和協議族的值永遠是相等的。這似乎顯得多此一舉了,既然值都是一樣的,為什麼要定義兩套呢?

我們回想一 下socket函式所做的工作:建立乙個插口!僅僅是建立乙個插口。在這個時候,這個插口應該是還沒有和任何位址繫結,直到你顯示呼叫bind或是 connect(connect會自動將插口繫結到乙個本地位址)。那麼也就是說,socket呼叫的時候,根本還沒有位址什麼事情。看了linux的源 **會進一步發現,linux下,網路協議被對映成多個域(domain),也就是socket函式中的domain,這個域是協議域,而不是位址域。所 以,我們看linux的man手冊中,對domain函式的可選引數的介紹都是pf_開頭的。但是令人迷惑的是,在win的msdn中,明確給出的可選參 數都是af_開頭的,並且也明確說了,第乙個引數是「位址域」引數,而不是「協議域」。那麼這裡有兩種可能,一:win下認為位址域和協議域是一碼事; 二:win在建立乙個插口的時候,是將其繫結到乙個位址域,而不是協議域(win下沒有協議域的概念)。這兩種解釋都是猜測,沒有什麼根據。也懶得查資料 了。呵呵

那麼,我們該怎麼辦?就目前來看,很好辦,無論你用af_*還是pf_*都是可以的,因為他們都是對等的。但是嚴謹的做法似乎應該是這樣的:

1、win下,一律使用af_*來建立插口

2、linux下,一律使用pf_*來建立插口

以 上的分析,似乎有點本本主義,但是對於我們常用的函式,可能很少去深入**其每乙個細節,因為我們所做的工作基本都是符合2/8原則的。可是,就如同,很 少有人檢查strcpy的返回值一樣,因為大家都認為這樣的函式「以常規的用法」一定會成功。寫這篇文章,也是想提醒自己,對每乙個細節都不應該放過。

socket 程式設計的埠和位址復用

int opt 1 if setsockopt sockfd,sol socket,so reuseaddr,const void opt,sizeof opt so reuseaddr允許啟動乙個監聽伺服器並 其眾所周知埠,即使以前建立的將此埠用做他們的 本地埠的連線仍存在。這通常是重啟監聽伺服器...

SOCKET 程式設計 獲取本機IP 位址

源程式 include include include include include include include include include include define port 7778 define maxdatasize 1024 int main setsockopt socke...

socket 程式設計之網路位址

在用 c c 編寫 socket 程式時,給相關函式傳入網路位址時總是會卡一下,有必要總結一下。struct sockaddr 16 位元組 第二個結構體是 struct sockaddr in 它用到了 struct in addr 這個結構體,定義如下 struct in addr s un b...