Sự khác biệt giữa AF_INET và PF_INET trong lập trình ổ cắm là gì?


205

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()bind().

Ngoài ra, làm thế nào để cung cấp địa chỉ IP trong sin_addrtrường?


Chỉ cần tìm kiếm trên mạng: một kết quả là thế này
Op De Cirkel

Tôi đã tự hỏi điều này là tốt. Chúng dường như được sử dụng thay thế cho nhau trong cuộc gọi ổ cắm giữa các lập trình viên khác nhau.
Matt

@MattH Cả hai đều giống nhau theo Hạt nhân Linux mới. Bạn có thể tìm thấy điều tương tự trong câu trả lời của Duke dưới đây.
SP Sandhu

Câu trả lời:


250

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.


68

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

chắc chắn Duke, nó cũng giống với các hạt nhân trước đó, ý tôi là hạt nhân trước phiên bản 3.0?
SP Sandhu

1
Như tôi đã biết, trong tất cả các phiên bản kernel và libc, PF_ * == AF_ *
Duke

Điều này có đúng trên các nền tảng không phải linux không?
Người tốt

1
Tôi nghĩ để đảm bảo, bạn cần kiểm tra tệp tiêu đề đi kèm :)
Duke

Trên Ubuntu / Debian tôi đã tìm thấy các định nghĩa AF trong/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik

48
  • AF = Địa chỉ gia đình
  • PF = Họ giao thức

Ý 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)liên kết (2) . Đối với sin_addrtrườ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); 

cảm ơn @codemac, tôi đã sử dụng addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); nhưng inet_pton () để làm gì?
SP Sandhu

còn đối với các trang man, khi tôi gõ man bind (2) hoặc man bind (), terminal sẽ đưa ra mã thông báo bất ngờ '(' trong khi man bind đưa ra lời giải thích về liên kết trong bash dựng sẵn. Làm thế nào để có được trang man cho bind (). Hàm bind ()?
SP Sandhu

@ jatt.beas: Cú pháp là man <section> <topic>, vd man 2 bind.
Frerich Raabe

11

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.


4

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.


3

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 đó trường hợp thực tế trong đó AF_INET và PF_INET không giống nhau.


6
Vui lòng giải thích. Tôi tìm thấy #define PF_INET AF_INETở Cygwin socket.h.
Hầu tước Lorne

3

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.

nhập mô tả hình ảnh ở đây


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
noobninja
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.