이 라이브러리는 C의 헤더 전용 크로스 플랫폼 mDNS 및 DNS-DS 라이브러리를 제공합니다. 최신 소스 코드는 항상 다음에서 사용할 수 있습니다.
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_open_ipv4
또는 mdns_socket_open_ipv6
으로 열린 소켓을 닫으려면 mdns_socket_close
호출하세요.
일회성 쿼리를 위해 소켓을 열거나 설정하려면 널 포인터 소켓 주소를 전달하거나 전달된 소켓 주소의 포트를 0으로 설정할 수 있습니다. 이렇게 하면 RFC에서 요구하는 대로 소켓이 임의의 임시 로컬 UDP 포트에 바인딩됩니다. 일회성 쿼리. 일회성 쿼리를 수행할 때 포트 5353에 바인딩하면 안 됩니다(자세한 내용은 RFC 참조).
들어오는 쿼리에 응답하여 서비스용 소켓을 열거나 설정하려면 포트가 5353(헤더에서 MDNS_PORT로 정의됨)으로 설정된 소켓 주소 구조를 전달해야 합니다. 다른 포트를 선택할 수 없습니다. 그렇지 않으면 들어오는 쿼리를 받을 수 없습니다.
기본 네트워크 인터페이스에서 검색 또는 쿼리를 수행하려면 소켓 생성/설정 함수에서 소켓 주소로 null 포인터를 전달할 수 있습니다. 그러면 소켓이 기본 네트워크 인터페이스에 바인딩됩니다. 그렇지 않으면 사용 가능한 인터페이스를 열거하고 적절한 소켓 주소를 생성/설정 함수에 전달해야 합니다. IPv4와 IPv6 모두에 대해 이 작업을 수행하는 예제 구현은 mdns.c
의 예제 프로그램을 참조하세요.
들어오는 쿼리에 대해 mDNS 서비스 응답을 수행하려는 경우 소켓이 모든 인터페이스에서 데이터를 수신하므로 모든 인터페이스에서 서비스 응답을 수행하기 위해 인터페이스를 열거할 필요가 없습니다. IPv4 및 IPv6 모두에 대한 서비스 소켓을 설정하는 예는 mdns.c
의 예제 프로그램을 참조하세요.
DNS-SD 서비스 검색 요청을 보내려면 mdns_discovery_send
사용하세요. 그러면 유니캐스트 응답을 요청하는 단일 멀티캐스트 패킷( _services._dns-sd._udp.local.
에 대한 단일 PTR 질문 레코드)이 전송됩니다.
검색 응답을 읽으려면 mdns_discovery_recv
사용하세요. 마지막 호출 이후 수신된 모든 레코드는 함수 호출에 제공된 콜백으로 파이프됩니다. 항목 유형은 MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
및 MDNS_ENTRYTYPE_ADDITIONAL
중 하나입니다.
단일 레코드에 대한 일회성 mDNS 쿼리를 보내려면 mdns_query_send
사용하세요. 그러면 주어진 레코드와 이름에 대해 단일 멀티캐스트 패킷이 전송됩니다(예: _http._tcp.local.
에 대한 PTR 레코드). 나중에 응답을 필터링하기 위해 쿼리에 대한 쿼리 ID를 선택적으로 전달하거나(RFC에서 권장하지 않는 경우에도 불구하고) 완전히 규정을 준수하도록 0을 전달할 수 있습니다. 이 함수는 이 쿼리와 관련된 쿼리 ID를 반환하며, 0이 아닌 경우 mdns_query_recv
에서 응답을 필터링하는 데 사용할 수 있습니다. 소켓이 포트 5353에 바인딩되어 있으면 멀티캐스트 응답이 요청되고, 그렇지 않으면 유니캐스트 응답이 요청됩니다.
쿼리 응답을 읽으려면 mdns_query_recv
사용하세요. 마지막 호출 이후 수신된 모든 레코드는 함수 호출에 제공된 콜백으로 파이프됩니다. query_id
매개변수가 0이 아닌 경우 함수는 지정된 쿼리 ID와 일치하지 않는 쿼리 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.
귀하가 제공하는 서비스(DNS-SD)에 대한 기록을 보내려면 mdns_discovery_answer
사용해야 합니다.
서비스 레코드 이름이 귀하가 제공하는 서비스인 경우 질문의 응답 유형 플래그에 따라 mdns_query_answer_unicast
또는 mdns_query_answer_multicast
사용하여 쿼리에 대한 응답으로 서비스 세부 정보를 다시 보냅니다.
주어진 함수에 대한 매개변수를 처리하는 방법에 대한 자세한 내용은 테스트 실행 가능 구현을 참조하세요.
포트 5353에서 쿼리를 수신하고 응답하는 mDNS 서비스를 제공하는 경우 서비스 시작 시 알림을 보내는 것이 좋습니다(원치 않는 답변으로). 서비스 시작 시 레코드를 알리려면 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
와 함께 cmake를 사용하거나 설치 및 find_package
mdns/20200130
인 conan을 사용하고 find_package
-> https://conan.io/center/mdns/20200130vcpkg install mdns
및 find_package