ไลบรารีนี้จัดเตรียมส่วนหัวเฉพาะไลบรารี mDNS และ DNS-DS ข้ามแพลตฟอร์มในภาษา C ซอร์สโค้ดล่าสุดจะมีให้ใช้งานเสมอที่
https://github.com/mjansson/mdns
ห้องสมุดนี้ถูกจัดเป็นสาธารณสมบัติ คุณสามารถแจกจ่ายต่อและ/หรือแก้ไขได้โดยไม่มีข้อจำกัดใดๆ
สร้างโดย Mattias Jansson (@maniccoder)
เซิร์ฟเวอร์ Discord สำหรับการสนทนา https://discord.gg/M8BwTQrt6c
ไลบรารีทำการค้นหาและบริการ DNS-SD รวมถึงการสืบค้นและตอบกลับ mDNS บันทึกเดียวแบบช็อตเดียว ไม่มีการจัดสรรหน่วยความจำโดยไลบรารี ผู้เรียกจะต้องส่งบัฟเฟอร์ที่ใช้ทั้งหมดเข้าไป ข้อมูลที่กำหนดเองสำหรับใช้ในการประมวลผลสามารถส่งผ่านได้โดยใช้ตัวชี้ทึบข้อมูลผู้ใช้
ไฟล์ปฏิบัติการทดสอบ mdns.c
สาธิตการใช้คุณสมบัติทั้งหมด รวมถึงการค้นหา การสืบค้น และการตอบกลับบริการ เอกสารประกอบที่นี่มีเจตนากระจัดกระจาย โค้ดตัวอย่างได้รับการบันทึกไว้อย่างดีและควรให้รายละเอียดทั้งหมด
ซ็อกเก็ตสำหรับการสื่อสาร mDNS สามารถเปิดได้โดยไลบรารีโดยใช้ mdns_socket_open_ipv4
หรือ mdns_socket_open_ipv6
หรือโดยการเริ่มต้นซ็อกเก็ตที่มีอยู่ด้วย mdns_socket_setup_ipv4
หรือ mdns_socket_setup_ipv6
ฟังก์ชันเปิด/ตั้งค่าซ็อกเก็ตจะเริ่มต้นซ็อกเก็ตด้วยความเป็นสมาชิกแบบหลายผู้รับ (รวมถึงลูปแบ็ค) และตั้งค่าเป็นโหมดที่ไม่ปิดกั้น
โทร mdns_socket_close
เพื่อปิดซ็อกเก็ตที่เปิดด้วย mdns_socket_open_ipv4
หรือ mdns_socket_open_ipv6
หากต้องการเปิด/ตั้งค่าซ็อกเก็ตสำหรับการสืบค้นแบบครั้งเดียว คุณสามารถส่งที่อยู่ซ็อกเก็ตตัวชี้ null หรือตั้งค่าพอร์ตในที่อยู่ซ็อกเก็ตที่ส่งผ่านเป็น 0 ซึ่งจะผูกซ็อกเก็ตเข้ากับพอร์ต UDP ภายในเครื่องชั่วคราวแบบสุ่มตามที่ RFCs ต้องการสำหรับ แบบสอบถามแบบครั้งเดียว คุณไม่ควรผูกเข้ากับพอร์ต 5353 เมื่อทำการสืบค้นแบบครั้งเดียว (ดูรายละเอียด RFC)
หากต้องการเปิด/ตั้งค่าซ็อกเก็ตสำหรับการบริการ ตอบสนองต่อคำถามที่เข้ามา คุณต้องส่งผ่านโครงสร้างที่อยู่ของซ็อกเก็ตโดยตั้งค่าพอร์ตเป็น 5353 (กำหนดโดย MDNS_PORT ในส่วนหัว) คุณไม่สามารถเลือกพอร์ตอื่นได้ ไม่เช่นนั้นคุณจะไม่ได้รับการสอบถามใดๆ เข้ามา
เมื่อต้องการค้นหาหรือสอบถามบนอินเทอร์เฟซเครือข่ายเริ่มต้น คุณสามารถส่งตัวชี้ null เป็นที่อยู่ซ็อกเก็ตในฟังก์ชันการสร้าง/ตั้งค่าซ็อกเก็ตได้ สิ่งนี้จะผูกซ็อกเก็ตเข้ากับอินเทอร์เฟซเครือข่ายเริ่มต้น มิฉะนั้น คุณควรระบุอินเทอร์เฟซที่มีอยู่ และส่งที่อยู่ซ็อกเก็ตที่เหมาะสมไปยังฟังก์ชันสร้าง/ตั้งค่า ดูโปรแกรมตัวอย่างใน mdns.c
สำหรับตัวอย่างการใช้งานการดำเนินการนี้สำหรับทั้ง IPv4 และ IPv6
หากคุณต้องการดำเนินการตอบกลับบริการ mDNS ต่อการสืบค้นที่เข้ามา คุณไม่จำเป็นต้องระบุอินเทอร์เฟซเพื่อดำเนินการตอบกลับบริการบนอินเทอร์เฟซทั้งหมด เนื่องจากซ็อกเก็ตรับข้อมูลจากอินเทอร์เฟซทั้งหมด ดูตัวอย่างโปรแกรมใน mdns.c
สำหรับตัวอย่างการตั้งค่าซ็อกเก็ตบริการสำหรับทั้ง IPv4 และ IPv6
หากต้องการส่งคำขอค้นพบบริการ DNS-SD ให้ใช้ mdns_discovery_send
สิ่งนี้จะส่งแพ็กเก็ตมัลติคาสต์เดียว (บันทึกคำถาม PTR เดียวสำหรับ _services._dns-sd._udp.local.
) เพื่อร้องขอการตอบกลับแบบผู้รับเดียว
หากต้องการอ่านคำตอบการค้นพบให้ใช้ mdns_discovery_recv
บันทึกทั้งหมดที่ได้รับตั้งแต่การโทรครั้งล่าสุดจะถูกส่งไปยังการโทรกลับที่ให้มาในการเรียกใช้ฟังก์ชัน ประเภทรายการจะเป็น MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
และ MDNS_ENTRYTYPE_ADDITIONAL
อย่างใดอย่างหนึ่ง
หากต้องการส่งข้อความค้นหา mDNS แบบ one-shot สำหรับบันทึกเดียว ให้ใช้ mdns_query_send
ซึ่งจะส่งแพ็กเก็ตมัลติคาสต์เดียวสำหรับบันทึกและชื่อที่กำหนด (เช่น บันทึก PTR สำหรับ _http._tcp.local.
) คุณสามารถเลือกส่ง ID การสืบค้นสำหรับการสืบค้นเพื่อการกรองการตอบกลับในภายหลัง (แม้ว่า RFC จะไม่สนับสนุน) หรือส่ง 0 เพื่อให้เป็นไปตามข้อกำหนดโดยสมบูรณ์ ฟังก์ชันส่งคืน ID การสืบค้นที่เกี่ยวข้องกับการสืบค้นนี้ ซึ่งหากไม่ใช่ศูนย์สามารถใช้เพื่อกรองการตอบกลับใน mdns_query_recv
ได้ หากซ็อกเก็ตถูกผูกไว้กับพอร์ต 5353 จะมีการร้องขอการตอบสนองแบบหลายผู้รับ มิฉะนั้นจะเป็นการตอบสนองแบบผู้รับเดียว
หากต้องการอ่านคำตอบแบบสอบถามให้ใช้ mdns_query_recv
บันทึกทั้งหมดที่ได้รับตั้งแต่การโทรครั้งล่าสุดจะถูกส่งไปยังการโทรกลับที่ให้มาในการเรียกใช้ฟังก์ชัน หากพารามิเตอร์ query_id
ไม่เป็นศูนย์ ฟังก์ชันจะกรองการตอบสนองใดๆ ที่มีรหัสการสืบค้นที่ไม่ตรงกับรหัสการสืบค้นที่กำหนด ประเภทรายการจะเป็น MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
และ MDNS_ENTRYTYPE_ADDITIONAL
อย่างใดอย่างหนึ่ง
โปรดทราบว่าซ็อกเก็ตที่เปิดสำหรับการสืบค้นแบบครั้งเดียวจากพอร์ตชั่วคราวจะไม่ได้รับคำตอบที่ไม่พึงประสงค์ (ประกาศ) เนื่องจากสิ่งเหล่านี้จะถูกส่งเป็นมัลติคาสต์บนพอร์ต 5353
หากต้องการส่งข้อความค้นหาหลายรายการในแพ็กเก็ตเดียวกัน ให้ใช้ mdns_multiquery_send
ซึ่งรับอาร์เรย์และจำนวนชื่อบริการและประเภทบันทึกเพื่อสอบถาม
หากต้องการฟังคำขอ DNS-SD ที่เข้ามาและการสืบค้น mDNS ซ็อกเก็ตสามารถเปิด/ตั้งค่าบนอินเทอร์เฟซเริ่มต้นโดยส่ง 0 เป็นที่อยู่ซ็อกเก็ตในการเรียกฟังก์ชันเปิด/ตั้งค่าซ็อกเก็ต (ซ็อกเก็ตจะได้รับข้อมูลจากอินเทอร์เฟซเครือข่ายทั้งหมด) จากนั้นเรียก mdns_socket_listen
เพื่อแจ้งเตือนข้อมูลขาเข้า หรือโดยการตั้งค่าโหมดการบล็อก และเรียก mdns_socket_listen
เพื่อบล็อกจนกว่าข้อมูลจะพร้อมใช้งานและแยกวิเคราะห์
ประเภทรายการที่ส่งไปยังการโทรกลับจะเป็น MDNS_ENTRYTYPE_QUESTION
และประเภทบันทึกจะระบุว่าควรตอบสนองกับบันทึกใด โปรแกรมตัวอย่างตอบสนองต่อบันทึก SRV, PTR, A และ AAAA ใช้ฟังก์ชัน mdns_string_extract
เพื่อรับสตริงชื่อของบันทึกการบริการที่ถูกถาม
หากชื่อบันทึกการบริการคือ _services._dns-sd._udp.local.
คุณควรใช้ mdns_discovery_answer
เพื่อส่งบันทึกบริการที่คุณให้ (DNS-SD)
หากชื่อบันทึกบริการเป็นบริการที่คุณให้ ให้ใช้ mdns_query_answer_unicast
หรือ mdns_query_answer_multicast
ขึ้นอยู่กับการตั้งค่าสถานะประเภทการตอบกลับในคำถามเพื่อส่งรายละเอียดบริการกลับไปเพื่อตอบสนองต่อคำถาม
ดูการทดสอบการใช้งานปฏิบัติการสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการจัดการพารามิเตอร์ให้กับฟังก์ชันที่กำหนด
หากคุณให้บริการ mDNS รับฟังและตอบคำถามบนพอร์ต 5353 เราขอแนะนำให้ส่งประกาศเมื่อเริ่มต้นบริการของคุณ (เป็นคำตอบที่ไม่พึงประสงค์) ใช้ mdns_announce_multicast
เพื่อประกาศบันทึกสำหรับบริการของคุณเมื่อเริ่มต้น และ mdns_goodbye_multicast
เพื่อประกาศการสิ้นสุดบริการเมื่อสิ้นสุด
ไฟล์ mdns.c
มีการใช้งานทดสอบปฏิบัติการโดยใช้ไลบรารีเพื่อทำแบบสอบถาม DNS-SD และ mDNS คอมไพล์ลงในไฟล์ปฏิบัติการและเรียกใช้เพื่อดูตัวเลือกบรรทัดคำสั่งสำหรับโหมดการค้นหา การสืบค้น และการบริการ
cl mdns.c /Zi /Fdmdns.pdb /link /out:mdns.exe ws2_32.lib iphlpapi.lib
gcc -o mdns mdns.c
clang -o mdns mdns.c
FetchContent
หรือติดตั้งและ find_package
mdns/20200130
และ find_package
-> https://conan.io/center/mdns/20200130vcpkg install mdns
และ find_package