ความแตกต่างระหว่าง AF_INET และ PF_INET ในการเขียนโปรแกรมซ็อกเก็ตคืออะไร?


205

ความแตกต่างระหว่าง AF_INET และ PF_INET ในการเขียนโปรแกรมซ็อกเก็ตคืออะไร?

ฉันสับสนระหว่างการใช้ AF_INET และ PF_INET ในและsocket()bind()

นอกจากนี้วิธีการให้ที่อยู่ IP ในsin_addrสาขา?


เพียงแค่ค้นหาสุทธิ: หนึ่งผลคือนี้
Op De Cirkel

ฉันก็สงสัยเช่นกัน ดูเหมือนว่าพวกเขาจะใช้แทนกันในการเรียกซ็อกเก็ตในหมู่ตัวแปลงสัญญาณที่แตกต่างกัน
แมตต์

@MattH พวกเขาทั้งสองเหมือนกันกับ Linux Kernels ใหม่ คุณสามารถหาคำตอบเดียวกันกับ Duke ได้ด้านล่าง
SP Sandhu

คำตอบ:


250

คู่มือการเขียนโปรแกรมเครือข่ายที่มีชื่อเสียงของ Beejให้คำอธิบายที่ดี:

ในเอกสารบางอย่างคุณจะเห็นการกล่าวถึง "PF_INET" ที่ลึกลับ นี่เป็นสัตว์ประหลาดที่ไม่มีวันพบเห็นได้ในธรรมชาติ แต่ข้าก็อาจจะอธิบายให้ชัดเจน เมื่อนานมาแล้วก็คิดว่าบางทีตระกูลที่อยู่ (สิ่งที่ "AF" ใน "AF_INET" หมายถึง) อาจรองรับโปรโตคอลหลายอย่างที่ถูกอ้างอิงโดยตระกูลโปรโตคอลของพวกเขา (สิ่งที่ "PF" ใน "PF_INET" หมายถึง )
นั่นไม่ได้เกิดขึ้น โอ้ดี ดังนั้นสิ่งที่ต้องทำคือใช้ AF_INET ใน struct sockaddr_in และ PF_INET ของคุณใน call to socket () แต่ในทางปฏิบัติคุณสามารถใช้ AF_INET ได้ทุกที่ และนั่นคือสิ่งที่ W. Richard Stevens ทำในหนังสือของเขานั่นคือสิ่งที่ฉันจะทำที่นี่


68

ฉันพบในซอร์สโค้ดเคอร์เนล Linux ที่ PF_INET และ AF_INET เหมือนกัน รหัสต่อไปนี้มาจากไฟล์ได้แก่ / linux / socket.h , บรรทัด 204 ของ Linux kernel 3.2.21 tree

/* Protocol families, same as address families. */
...
#define PF_INET     AF_INET

แน่นอนว่า Duke มันเหมือนกันกับเมล็ดก่อนหน้าหรือไม่ฉันหมายถึงเมล็ดก่อนรุ่น 3.0 หรือไม่
SP Sandhu

1
ตามที่ฉันรู้ในเคอร์เนลและ libc ทุกรุ่น PF_ * == AF_ *
Duke

สิ่งนี้เป็นจริงหรือไม่บนแพลตฟอร์มที่ไม่ใช่ Linux
คนดี

1
ผมคิดว่าเพื่อให้แน่ใจว่าคุณต้องตรวจสอบแฟ้มหัวรวม :)
ดยุค

บน Ubuntu / Debian ฉันพบคำจำกัดความ AF ใน/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik

48
  • AF = ตระกูลที่อยู่
  • PF = ตระกูลโปรโตคอล

ความAF_INETหมายหมายถึงที่อยู่จากอินเทอร์เน็ตที่อยู่ IP โดยเฉพาะ PF_INETหมายถึงอะไรในโปรโตคอลมักจะซ็อกเก็ต / พอร์ต

พิจารณาอ่านหน้าคนสำหรับซ็อกเก็ต (2)และผูก (2) สำหรับsin_addrฟิลด์เพียงทำสิ่งต่อไปนี้เพื่อตั้งค่า:

struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); 

ขอบคุณ @cememac ฉันได้ใช้ addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); แต่ inet_pton () มีไว้เพื่ออะไร
SP Sandhu

สำหรับ man pages เมื่อฉันพิมพ์ man bind (2) หรือ man bind () เทอร์มินัลจะให้โทเค็นที่ไม่คาดคิด '(' ข้อผิดพลาดในขณะที่ man bind ให้คำอธิบายเกี่ยวกับ bind ใน bash builtins) ฟังก์ชั่นผูก ()?
SP Sandhu

@ jatt.beas: ไวยากรณ์เช่นman <section> <topic> man 2 bind
Frerich Raabe

11

อันที่จริง AF_ และ PF_ นั้นเหมือนกัน มีบางคำใน Wikipedia ที่จะทำให้คุณสับสน

แนวคิดการออกแบบดั้งเดิมของอินเตอร์เฟสซ็อกเก็ตที่แยกความแตกต่างระหว่างประเภทโปรโตคอล (ตระกูล) และประเภทที่อยู่เฉพาะที่แต่ละประเภทอาจใช้ มีการคาดการณ์ว่ากลุ่มโปรโตคอลอาจมีที่อยู่หลายประเภท ประเภทที่อยู่ถูกกำหนดโดยค่าคงที่เชิงสัญลักษณ์เพิ่มเติมโดยใช้คำนำหน้า AF_ แทน PF_ AF_-identifiers มีไว้สำหรับโครงสร้างข้อมูลทั้งหมดที่จัดการเฉพาะกับประเภทที่อยู่ไม่ใช่ตระกูลโปรโตคอล อย่างไรก็ตามแนวคิดของการแยกโพรโทคอลและประเภทที่อยู่ยังไม่พบการสนับสนุนการใช้งานและค่าคงที่ AF_ ถูกกำหนดโดยตัวระบุโปรโตคอลที่สอดคล้องกันทำให้การแยกความแตกต่างระหว่าง AF_ กับ PF_ ยังคงเป็นข้อโต้แย้งทางเทคนิค แน่นอนว่ามีความสับสนเกิดขึ้นมากมายในการใช้ทั้งสองรูปแบบอย่างเหมาะสม


4

AF_INET = รูปแบบที่อยู่, อินเทอร์เน็ต = ที่อยู่ IP

PF_INET = รูปแบบแพ็คเก็ต, อินเทอร์เน็ต = IP, TCP / IP หรือ UDP / IP

AF_INET เป็นตระกูลที่อยู่ที่ใช้สำหรับซ็อกเก็ตที่คุณสร้าง (ในกรณีนี้คือที่อยู่อินเทอร์เน็ตโพรโทคอล) ตัวอย่างเช่นเคอร์เนล Linux สนับสนุนตระกูลที่อยู่อื่น ๆ 29 รายการเช่น UNIX sockets และ IPX และการสื่อสารกับ IRDA และ Bluetooth (AF_IRDA และ AF_BLUETOOTH แต่ไม่แน่ใจว่าคุณจะใช้สิ่งเหล่านี้ในระดับต่ำ)

ส่วนใหญ่ที่ติดกับ AF_INET สำหรับการเขียนโปรแกรมซ็อกเก็ตผ่านเครือข่ายเป็นตัวเลือกที่ปลอดภัยที่สุด

ความหมาย AF_INET หมายถึงที่อยู่จากอินเทอร์เน็ตที่อยู่ IP โดยเฉพาะ

PF_INET หมายถึงสิ่งใด ๆ ในโปรโตคอลโดยปกติจะเป็นซ็อกเก็ต / พอร์ต


3

มีสถานการณ์ที่สำคัญ

หากคุณส่ง AF_INET ไปที่socket()Cygwin ซ็อกเก็ตของคุณอาจจะถูกรีเซ็ตแบบสุ่มหรือไม่ก็ได้ การส่งผ่าน PF_INET ช่วยให้มั่นใจได้ว่าการเชื่อมต่อทำงานได้อย่างถูกต้อง

Cygwin ยอมรับตนเองเป็นอย่างมากสำหรับการเขียนโปรแกรมซ็อกเก็ต แต่เป็นกรณีจริงที่ AF_INET และ PF_INET ไม่เหมือนกัน


6
กรุณาอธิบาย. ผมพบว่า#define PF_INET AF_INETใน socket.hCygwin
มาร์ควิสแห่ง Lorne

3

ตรวจสอบการแก้ไขไฟล์ส่วนหัวเป็นปัญหา หนึ่งสามารถตรวจสอบว่ามีระบบรวบรวม

สำหรับระบบของฉัน AF_INET == PF_INET

AF == ตระกูลที่อยู่และ PF == ตระกูลโปรโตคอล

ตระกูลโปรโตคอลเช่นเดียวกับตระกูลแอดเดรส

ป้อนคำอธิบายรูปภาพที่นี่


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
noobninja
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.