2015-11-05 59 views
3

在socket編程中,尤其是在處理struct sockaddr_un類型的Unix域套接字,一些people useoffsetof()計算sockaddr_un結構的尺寸喜歡 -使用offsetof()而不是sizeof()與套接字是否有區別?

struct sockaddr_un { 
    sa_family_t sun_family;    /* AF_UNIX */ 
    char  sun_path[108];   /* pathname */ 
}; 
size = (offsetof (struct sockaddr_un, sun_path) 
      + strlen (name.sun_path)); 

在一些other places,他們使用

size = sizeof(struct sockaddr_un) 

我知道第一種方法佔用較短的路徑名,第二種方法給出固定的最大大小,而不考慮實際路徑長度。

它是否真的有所作爲bind這個函數傳遞了這個值?如果不是,這兩個可以互換使用嗎?

+1

第二個鏈接中的文檔說'大小'需要至少包含空終止符,因此第一個示例中的代碼需要'+ 1'。 – user2357112

+0

'sockaddr_un'和'sockaddr_in'打算拼寫不同,還是其中一個拼寫錯誤? –

+0

@凱瑟湯普森。我的意思是聯合國,不在英寸,糾正它。 –

回答

2

offsetof考慮了C編譯器在基本成員大小後可能添加的任何填充。但是,如果使用包含由C編譯器添加的填充的C結構定義網絡數據包,則會出現更大的問題!事實上,我會確保添加了一個測試用例,以確保兩個方法返回相同的大小,以防止不正確的編譯選項更改填充規則。

在這個問題的背景下,不,它沒有任何區別綁定

+1

'sizeof'版本如何不填充?還要注意,這些'struct's並不意味着通過套接字發送。他們*描述*插座。 – 5gon12eder

+0

因爲通常,完成結構所需的最小填充可能小於後續成員所需的填充。例如,在舊的32位英特爾使用中,結構將只填充到32位,但如果您有雙精度型,編譯器選項可以強制將偏移量強制爲64位填充 - 而offsetof將捕獲該情況。無論如何,過度的巧妙和解決錯誤的問題! – cliffordheath

+0

爲了進一步闡明,只允許包含單個char成員的結構(例如)具有char對齊方式,但只要添加一個具有較大對齊方式的成員,整個結構就需要更大的對齊方式。 – cliffordheath

0

我會說你發佈的offsetof版本不正確。它應該至少有一個+1,因爲路徑被定義爲一個以空字符結尾的字符串,這就是內核返回的長度,例如從getsockname()

即使使用+1,我也沒有看到在簡單的東西上使用複雜的東西。它確實節省了幾個字節傳輸到內核,但bind()和朋友幾乎不是速率確定步驟。

相關問題