ความแตกต่างระหว่าง AF_INET และ PF_INET ในการเขียนโปรแกรมซ็อกเก็ตคืออะไร?
ฉันสับสนระหว่างการใช้ AF_INET และ PF_INET ในและsocket()
bind()
นอกจากนี้วิธีการให้ที่อยู่ IP ในsin_addr
สาขา?
ความแตกต่างระหว่าง AF_INET และ PF_INET ในการเขียนโปรแกรมซ็อกเก็ตคืออะไร?
ฉันสับสนระหว่างการใช้ AF_INET และ PF_INET ในและsocket()
bind()
นอกจากนี้วิธีการให้ที่อยู่ IP ในsin_addr
สาขา?
คำตอบ:
คู่มือการเขียนโปรแกรมเครือข่ายที่มีชื่อเสียงของ Beejให้คำอธิบายที่ดี:
ในเอกสารบางอย่างคุณจะเห็นการกล่าวถึง "PF_INET" ที่ลึกลับ นี่เป็นสัตว์ประหลาดที่ไม่มีวันพบเห็นได้ในธรรมชาติ แต่ข้าก็อาจจะอธิบายให้ชัดเจน เมื่อนานมาแล้วก็คิดว่าบางทีตระกูลที่อยู่ (สิ่งที่ "AF" ใน "AF_INET" หมายถึง) อาจรองรับโปรโตคอลหลายอย่างที่ถูกอ้างอิงโดยตระกูลโปรโตคอลของพวกเขา (สิ่งที่ "PF" ใน "PF_INET" หมายถึง )
นั่นไม่ได้เกิดขึ้น โอ้ดี ดังนั้นสิ่งที่ต้องทำคือใช้ AF_INET ใน struct sockaddr_in และ PF_INET ของคุณใน call to socket () แต่ในทางปฏิบัติคุณสามารถใช้ AF_INET ได้ทุกที่ และนั่นคือสิ่งที่ W. Richard Stevens ทำในหนังสือของเขานั่นคือสิ่งที่ฉันจะทำที่นี่
ฉันพบในซอร์สโค้ดเคอร์เนล 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
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
ความAF_INET
หมายหมายถึงที่อยู่จากอินเทอร์เน็ตที่อยู่ IP โดยเฉพาะ PF_INET
หมายถึงอะไรในโปรโตคอลมักจะซ็อกเก็ต / พอร์ต
พิจารณาอ่านหน้าคนสำหรับซ็อกเก็ต (2)และผูก (2) สำหรับsin_addr
ฟิลด์เพียงทำสิ่งต่อไปนี้เพื่อตั้งค่า:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
man 2 bind
อันที่จริง AF_ และ PF_ นั้นเหมือนกัน มีบางคำใน Wikipedia ที่จะทำให้คุณสับสน
แนวคิดการออกแบบดั้งเดิมของอินเตอร์เฟสซ็อกเก็ตที่แยกความแตกต่างระหว่างประเภทโปรโตคอล (ตระกูล) และประเภทที่อยู่เฉพาะที่แต่ละประเภทอาจใช้ มีการคาดการณ์ว่ากลุ่มโปรโตคอลอาจมีที่อยู่หลายประเภท ประเภทที่อยู่ถูกกำหนดโดยค่าคงที่เชิงสัญลักษณ์เพิ่มเติมโดยใช้คำนำหน้า AF_ แทน PF_ AF_-identifiers มีไว้สำหรับโครงสร้างข้อมูลทั้งหมดที่จัดการเฉพาะกับประเภทที่อยู่ไม่ใช่ตระกูลโปรโตคอล อย่างไรก็ตามแนวคิดของการแยกโพรโทคอลและประเภทที่อยู่ยังไม่พบการสนับสนุนการใช้งานและค่าคงที่ AF_ ถูกกำหนดโดยตัวระบุโปรโตคอลที่สอดคล้องกันทำให้การแยกความแตกต่างระหว่าง AF_ กับ PF_ ยังคงเป็นข้อโต้แย้งทางเทคนิค แน่นอนว่ามีความสับสนเกิดขึ้นมากมายในการใช้ทั้งสองรูปแบบอย่างเหมาะสม
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 หมายถึงสิ่งใด ๆ ในโปรโตคอลโดยปกติจะเป็นซ็อกเก็ต / พอร์ต
มีสถานการณ์ที่สำคัญ
หากคุณส่ง AF_INET ไปที่socket()
Cygwin ซ็อกเก็ตของคุณอาจจะถูกรีเซ็ตแบบสุ่มหรือไม่ก็ได้ การส่งผ่าน PF_INET ช่วยให้มั่นใจได้ว่าการเชื่อมต่อทำงานได้อย่างถูกต้อง
Cygwin ยอมรับตนเองเป็นอย่างมากสำหรับการเขียนโปรแกรมซ็อกเก็ต แต่เป็นกรณีจริงที่ AF_INET และ PF_INET ไม่เหมือนกัน
#define PF_INET AF_INET
ใน socket.h
Cygwin
ตรวจสอบการแก้ไขไฟล์ส่วนหัวเป็นปัญหา หนึ่งสามารถตรวจสอบว่ามีระบบรวบรวม
สำหรับระบบของฉัน AF_INET == PF_INET
AF == ตระกูลที่อยู่และ PF == ตระกูลโปรโตคอล
ตระกูลโปรโตคอลเช่นเดียวกับตระกูลแอดเดรส
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h