Sự khác biệt giữa AF_INET và PF_INET trong lập trình ổ cắm là gì?
Tôi đang bối rối giữa việc sử dụng AF_INET và PF_INET trong socket()
và bind()
.
Ngoài ra, làm thế nào để cung cấp địa chỉ IP trong sin_addr
trường?
Sự khác biệt giữa AF_INET và PF_INET trong lập trình ổ cắm là gì?
Tôi đang bối rối giữa việc sử dụng AF_INET và PF_INET trong socket()
và bind()
.
Ngoài ra, làm thế nào để cung cấp địa chỉ IP trong sin_addr
trường?
Câu trả lời:
Hướng dẫn lập trình mạng nổi tiếng của Beej đưa ra một lời giải thích hay:
Trong một số tài liệu, bạn sẽ thấy đề cập đến một "PF_INET" huyền bí. Đây là một con thú etherial kỳ lạ hiếm khi được nhìn thấy trong tự nhiên, nhưng tôi cũng có thể làm rõ nó một chút ở đây. Cách đây rất lâu, người ta đã nghĩ rằng có thể một họ địa chỉ (chữ "AF" trong "AF_INET" là gì) có thể hỗ trợ một số giao thức được tham chiếu bởi họ giao thức của họ (chữ "PF" trong "PF_INET" là viết tắt của ).
Điều đó đã không xảy ra. Ồ tốt Vì vậy, điều cần làm là sử dụng AF_INET trong struct sockaddr_in và PF_INET trong lệnh gọi của bạn tới socket (). Nhưng thực tế mà nói, bạn có thể sử dụng AF_INET ở mọi nơi. Và, vì đó là những gì W. Richard Stevens làm trong cuốn sách của mình, đó là những gì tôi sẽ làm ở đây.
Tôi đã tìm thấy trong mã nguồn nhân Linux rằng PF_INET và AF_INET giống nhau. Đoạn mã sau lấy từ tệp bao gồm / linux / socket.h , dòng 204 của Linux kernel 3.2.21 cây.
/* Protocol families, same as address families. */
...
#define PF_INET AF_INET
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Ý nghĩa, AF_INET
đề cập đến các địa chỉ từ internet, địa chỉ IP cụ thể. PF_INET
đề cập đến bất cứ điều gì trong giao thức, thường là ổ cắm / cổng.
Xem xét việc đọc các trang man cho socket (2) và liên kết (2) . Đối với sin_addr
trường, chỉ cần làm một cái gì đó như sau để thiết lập nó:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
, vd man 2 bind
.
Trên thực tế, AF_ và PF_ là cùng một thứ. Có một số từ trên Wikipedia sẽ xóa sự nhầm lẫn của bạn
Khái niệm thiết kế ban đầu của giao diện ổ cắm được phân biệt giữa các loại giao thức (họ) và các loại địa chỉ cụ thể mà mỗi loại có thể sử dụng. Nó đã được hình dung rằng một họ giao thức có thể có một số loại địa chỉ. Các loại địa chỉ được xác định bởi các hằng ký hiệu bổ sung, sử dụng tiền tố AF_ thay vì PF_. Các định danh AF_ được dành cho tất cả các cấu trúc dữ liệu liên quan cụ thể đến loại địa chỉ và không phải là họ giao thức. Tuy nhiên, khái niệm phân tách giao thức và loại địa chỉ này không tìm thấy hỗ trợ triển khai và các hằng số AF_ được định nghĩa đơn giản bởi định danh giao thức tương ứng, đưa ra sự khác biệt giữa AF_ so với PF_ là một đối số kỹ thuật không có hậu quả thực tế quan trọng. Thật vậy, nhiều nhầm lẫn tồn tại trong việc sử dụng đúng cả hai hình thức.
AF_INET = Định dạng địa chỉ, Internet = Địa chỉ IP
PF_INET = Định dạng gói, Internet = IP, TCP / IP hoặc UDP / IP
AF_INET là họ địa chỉ được sử dụng cho ổ cắm bạn đang tạo (trong trường hợp này là địa chỉ Giao thức Internet). Ví dụ, nhân Linux hỗ trợ 29 họ địa chỉ khác như ổ cắm UNIX và IPX, cũng như liên lạc với IRDA và Bluetooth (AF_IRDA và AF_BLUETOOTH, nhưng chắc chắn bạn sẽ sử dụng chúng ở mức độ thấp như vậy).
Đối với hầu hết các phần gắn bó với AF_INET để lập trình ổ cắm qua mạng là tùy chọn an toàn nhất.
Có nghĩa là, AF_INET đề cập đến các địa chỉ từ internet, địa chỉ IP cụ thể.
PF_INET đề cập đến bất cứ điều gì trong giao thức, thường là ổ cắm / cổng.
Có những tình huống mà nó quan trọng.
Nếu bạn chuyển AF_INET sang socket()
Cygwin, ổ cắm của bạn có thể hoặc không thể được đặt lại ngẫu nhiên. Vượt qua PF_INET đảm bảo rằng kết nối hoạt động đúng.
Cygwin tự thừa nhận là một mớ hỗn độn lớn cho lập trình socket, nhưng đó là trường hợp thực tế trong đó AF_INET và PF_INET không giống nhau.
#define PF_INET AF_INET
ở Cygwin socket.h
.
Kiểm tra tệp tiêu đề giải quyết vấn đề. Người ta có thể kiểm tra trình biên dịch hệ thống.
Đối với hệ thống của tôi, AF_INET == PF_INET
AF == Địa chỉ gia đình và PF == Giao thức gia đình
Họ gia đình, giống như địa chỉ gia đình.
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h