2015-09-04 82 views
2

我正在嘗試學習網絡編程和C中的過程。我對sockaddr這是一個通用地址和sockaddr_in的結構感到困惑。我的書有這樣一段話:類型轉換sockaddr結構

因此,我們可以在一個SOCKADDR_IN領域填補再投(一 指針)到一個(指針)的sockaddr並把它傳遞到插座 功能,它看着sa_family字段來學習實際的類型,然後 轉換回適當的類型。

但在我看來,這兩個結構應該是兼容的嗎?其中有兩個字段,

struct sockaddr { 
    sa_family_t sa_family; 
    char sa_data[14]; 
}; 

其他有大量

struct in_addr { 
    uint32_t s_addr; 
}; 

struct sockaddr_in { 
    sa_family_t sin_family; 
    in_port_t sin_port; 
    struct in_addr sin_addr; 
    char sin_zero[8]; 
}; 

他們都有大小16在內存中。我想這就是爲什麼他們零填充sockaddr_in結構,以使鑄造?我仍然感到困惑 - 如果你不立刻投了,能鑄造出有意義的東西嗎?這是否只是一個臨時演員,利用sa_family_t字段駐留在第一個N位的事實?

+0

對於網絡相關的所有東西請參閱[** Beej的網絡編程指南**](http://beej.us/guide/bgnet/)。這是一個很好的網絡編程參考/教程。只有** 100%**適用於您當前的問題。 –

回答

0

您沒有被要求投下struct,而是一個指向它的指針。

潛在呼叫的相關信息,即參考哪個struct,可以從sin_family成員中獲得,該成員在任何情況下都可用。

所以實際上,轉換隻是爲了靜音編譯器,因爲所謂的函數需要一個指向struct sockaddr的指針,但實際上會傳遞一個指向不同類型的指針。

+0

「沉默編譯器」是不是這個UB? – usr

+0

@usr:如果生成的指針未正確對齊,它只會調用未定義的行爲。 C11草案6.3.2.3/7:「*指向對象類型的指針可能會轉換爲指向不同對象類型的指針。如果結果指針未針對引用類型正確對齊,則行爲爲 未定義。*」 – alk

+0

好吧,創建指針可能會被允許,但解除引用並不像我所知的那樣。 – usr