Tôi có thể thấy lý do tại sao nó hữu ích khi đúc sockaddr
đến sockaddr_in
, nhưng tôi không hiểu làm thế nào điều này là có thể. Từ những gì tôi đã đọc, chúng có cùng kích thước và sockaddr_in
được thêm vào với sin_zero
để làm cho nó có cùng kích thước. Tôi muốn biết làm thế nào trình biên dịch biết nơi để lấy thông tin từ sockaddr_in
nếu nó được bố trí khác nhau để sockaddr
.Tại sao chúng ta có thể bỏ sockaddr vào sockaddr_in
Trả lời
Có thể vì bạn thường truyền con trỏ chứ không phải cấu trúc. Bạn làm những gì trong ngôn ngữ tự nhiên có nghĩa là "hãy xử lý con trỏ này đến một số socket structure
làm con trỏ đến một số internet socket structure
thay thế". Trình biên dịch không có vấn đề gì để giải thích lại con trỏ.
Dưới đây là mô tả chi tiết được đưa lên từ nhận xét:
Một sockaddr
là 16 byte trong kích thước - hai byte đầu tiên là sa_family
, và 14 byte còn lại là những sa_data
đó là dữ liệu tùy ý. A sockaddr_in
cũng có kích thước 16 byte - 2 byte đầu tiên là sin_family
(luôn là AF_INET
), 2 byte tiếp theo là sin_port
, 4 byte tiếp theo là sin_addr
(địa chỉ IP) và 8 byte cuối cùng là sin_zero
không được sử dụng trong IPv4 và chỉ được cung cấp để đảm bảo 16 byte. Bằng cách này, trước hết bạn có thể xem sockaddr.sa_family
và nếu đó là AF_INET
thì hãy giải thích toàn bộ sockaddr
dưới dạng sockaddr_in
.
A sockaddr_in
không được lưu trữ bên trong trường sockaddr.sa_data
. Toàn bộ sockaddr
là toàn bộ sockaddr_in
(khi sockaddr.sa_family
là AF_INET
, tức là). Nếu bạn lấy một con trỏ sockaddr*
và bỏ nó vào một con trỏ sockaddr_in*
, sau đó:
sockaddr.sa_family
làsockaddr_in.sin_family
- byte 0-1 của
sockaddr.sa_data
làsockaddr_in.sin_port
- byte 2-5 là
sockaddr_in.sin_addr
- byte 6 -13 là
sockaddr_in.sin_zero
.
Có vẻ lạ vì biến được cho là lưu trữ địa chỉ trong sockaddr là sa_data là char [14], nhưng sockaddr_in sử dụng dấu ngắn chưa được ký. Tôi giả định rằng trình biên dịch sẽ đọc số byte chưa ký đầu tiên từ char [14] và làm cho địa chỉ đó, và phần còn lại của char [14] là dữ liệu được gửi đi? Ngoài ra, nếu tôi thêm kích thước của hai cấu trúc, chúng có vẻ không giống kích thước. sin_zero có vẻ quá lớn. Tôi chỉ tring để có được những gì đang xảy ra ở đây! –
Một 'sockaddr' có kích thước 16 byte - hai byte đầu tiên là' sa_family' và 14 byte còn lại là 'sa_data' là dữ liệu tùy ý. Một 'sockaddr_in' cũng có kích thước 16 byte - 2 byte đầu tiên là' sin_family' (luôn là 'AF_INET'), 2 byte tiếp theo là' sin_port', 4 byte tiếp theo là 'sin_addr' (địa chỉ IP) và 8 byte cuối cùng là 'sin_zero' không được sử dụng trong IPv4 và chỉ được cung cấp để đảm bảo 16 byte. Bằng cách này, bạn có thể nhìn vào 'sockaddr.sa_family' trước tiên, và nếu nó là' AF_INET' thì giải thích toàn bộ 'sockaddr' là' sockaddr_in'. –
Một 'sockaddr_in' không được lưu trữ bên trong trường' sockaddr.sa_data'. Toàn bộ 'sockaddr' ** là ** toàn bộ' sockaddr_in' (khi 'sockaddr.sa_family' là' AF_INET', nghĩa là). Nếu bạn lấy một con trỏ 'sockaddr *' và đưa nó vào một con trỏ 'sockaddr_in *', 'sockaddr.sa_family' là' sockaddr_in.sin_family', byte 0-1 của 'sockaddr.sa_data' là' sockaddr_in.sin_port', bytes 2-5 là 'sockaddr_in.sin_addr' và byte 6-13 là' sockaddr_in.sin_zero'. –