학습자료/Java 2013. 2. 13. 14:52

zeroconf 간단 요약 -

http://cozyboy.tistory.com/entry/zero-configuration-networking

 

추가.

Bonjour browser download site

http://hobbyistsoftware.com/bonjourbrowser

이 프로그램을 사용하면 어떠한 장비들이 있는지 간단하게 볼수 있다.

굳이 검색할 장비를 세팅하지 않아도 나도모르게 내 컴퓨터엔, 혹은 주위에 이미 존재 하고 있을수도 있다.

아래 소스로 프로그램후, 위의 서비스 타입([ex] : _adisk._tcp)을 이용하여 검색해보자. 표시가 잘 된다면 기본은 성공이다.

 

 


목차는

- 환경

- avahi(검색할 리모트 네트워크 장비) conf file 내용

- 테스트 코드

- 결과

- 간략 설명

- 오픈소스 JBonjourBrowser 스샷 및 다운로드 위치 


 

 

  • 환경

zeroconf 구현물인 avahi는 리눅스에서 running 상태이고,

 

애플의 bonjour sdk에 있는 dnssd.jar를 이용하여

윈도우에서 리눅스 장비를 탐지 할 수 있다.

 

avahi는 왠만하면 OS설치시 깔려있다. 깔려있지 않을 시, 설치 및 구동 시켜야 한다.

 

avahi-dnsconfd 는 추가로 설치함.(아마 avahi service conf가 바뀌면 실시간으로 모니터링 하는 데몬인것 같다. 테스트 할시 용의하므로 추가 설치)

 

/etc/avahi/service/* 가 service config다

 

  • avahi service conf의 min.service파일 내용.

<?xml version='1.0' standalone='no'?><!--*-nxml-*--> <!DOCTYPE service-group SYSTEM 'avahi-service.dtd'> <service-group> <name>UCS-1078d23f2fbb</name> <service> <type>_cozy._tcp</type> <port>22</port> <txt-record>ID=cozy--</txt-record> <txt-record>NAME=min</txt-record> <txt-record>AGE=26</txt-record> <txt-record>COR=Gluesys</txt-record> </service> </service-group>


 

  • [테스트 코드]

bonjour sdk for window 다운 : https://developer.apple.com/bonjour/

- 아이디 만들고 다운받으면 된다. 분명 아이디 안만들고 어디선가 받았는데 못 찾겠음.

 

package test.dns;

/*
 * Browse -> Resolve(a single SRV record and a single TXT record에 적합하다) -> Query listen(txt record가 여러라인일때 쓴다.)
 * */

import com.apple.dnssd.BrowseListener;
import com.apple.dnssd.DNSSD;
import com.apple.dnssd.DNSSDException;
import com.apple.dnssd.DNSSDService;
import com.apple.dnssd.QueryListener;
import com.apple.dnssd.ResolveListener;
import com.apple.dnssd.TXTRecord;

public class Main implements BrowseListener, QueryListener, ResolveListener{

 private DNSSDService monitorQ = null;
 
 public static void browse() throws DNSSDException, InterruptedException{
  System.out.println("TestBrowse Starting");

  DNSSDService b = DNSSD.browse("_min._tcp", new Main());
  
  System.out.println("TestBrowse Running");
  Thread.sleep(500);
  System.out.println("TestBrowse Stopping");
  b.stop();
 }

 
 public void TestResolveWithMonitoring(String serviceName, String regType,  String domain)
   throws DNSSDException, InterruptedException {
  System.out.println("TestResolve Starting==================================");
  DNSSDService r = DNSSD.resolve(0, DNSSD.ALL_INTERFACES, serviceName, regType, domain, this);
  System.out.println("TestResolve Running");
   
  /*시간이 너무 짧을시, txt-record가  갯수만큼 안나온다.*/
  try {
   Thread.sleep(500);                  
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(-1);
  }
  System.out.println("TestResolve Stopping===================================");
  if (monitorQ == null)
   r.stop();
  else
   monitorQ.stop();
  
 }
 
 
 public static void main(String[] args) {
  try { browse(); }
  catch (Exception e) {
   e.printStackTrace();
   System.exit(-1);
  }
 }

 /** Browser listener`s  */
 @Override
 public void serviceFound( DNSSDService browser,  int flags, int iflndex,
    String serviceName, String regType, String domain) {
  // TODO Auto-generated method stub
  System.out.print("\t(Browsing) Service Found : ");
  System.out.println("browser:" + browser + ", flags:" + flags
    + ", iflndex:" + iflndex + ", serviceName:" + serviceName+ ", regType:" + regType+ ", domain:" + domain);
 
  try {
   
   TestResolveWithMonitoring(serviceName, regType, domain);
   
  } catch (DNSSDException | InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 @Override
 public void serviceLost(DNSSDService arg0, int arg1, int arg2, String arg3,
   String arg4, String arg5) {
  // TODO Auto-generated method stub
  System.out.println("Add flags:" + arg0 + ", ifIndex:" + arg1
    + ", Name:" + arg2 + ", Type:" + arg3 + ", Type4:" + arg4
    + ", Type5:" + arg5);
 }

 


 /** Query listener`s  */
 public void queryAnswered(DNSSDService query, int flags, int ifIndex,
   String fullName, int rrtype, int rrclass, byte[] rdata, int ttl) {
   TXTRecord txtRecord = new TXTRecord(rdata);
   System.out.println("\n+++txtRecord Size is :"+txtRecord.size()+"\n");
   System.out.println("\t(Query) txtRecord is : ");
   for (int i = 0; i < txtRecord.size(); i++) {
    String key = txtRecord.getKey(i);
    String value = txtRecord.getValueAsString(i);
    if (key.length() > 0) {
     
     System.out.println("\t\t" + key + "=" + value);
    }
   }
 }

 
 /** Resolve listener`s  */
 public void serviceResolved(DNSSDService resolver, int flags, int ifIndex,
   String fullName, String hostName, int port, TXTRecord txtRecord) {
  System.out.print("\t(Resolve)Service Resolved: " + hostName + ":" + port);
  System.out.println(" Flags: " + flags + ", ifIndex: " + ifIndex + ", FQDN: " + fullName);

  // Now that we've got a resolve result,
  // start monitoring the TXT record and stop the resolve call.
  try {
   monitorQ = DNSSD.queryRecord(0, ifIndex, fullName, 16, 1, this);
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(-1);
  }
 
  /*try {
   Thread.sleep(1);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }*/
  
  resolver.stop();
 }
 
 /** all listener`s  */
 @Override
 public void operationFailed(DNSSDService service, int errorCode) {
  System.out.println("listener failed " + errorCode);
  System.exit(-1);
 }

}

 

 

  • [결과] 

TestBrowse Starting
TestBrowse Running
 (Browsing) Service Found : browser:com.apple.dnssd.AppleBrowser@31731334, flags:2, iflndex:11, serviceName:min_test, regType:_min._tcp., domain:local.
TestResolve Starting==================================
TestResolve Running
 (Resolve)Service Resolved: min.local.:22 Flags: 0, ifIndex: 11, FQDN: min_test._min._tcp.local.

+++txtRecord Size is :4

 (Query) txtRecord is :
  ID=cozy--
  NAME=min
  AGE=26
  COR=Gluesys
TestBrowse Stopping
TestResolve Stopping===================================

 

 


 

  • 간략 설명

BrowseListener,  ResolveListener, QueryListener 가 구현되어있다.

 

BrowseListener로는  (serviceFound )

browser:com.apple.dnssd.AppleBrowser@31731334, flags:2, iflndex:11, serviceName:min_test, regType:_min._tcp., domain:local.

를 얻는다.

 

ResolveListener로는 (serviceResolved)

(Resolve)Service Resolved: min.local.:22 Flags: 0, ifIndex: 11, FQDN: min_test._min._tcp.local.

 

☞ QueryListener는 단일 txtRecord를 얻는데 사용된다. 멀티라인의 txtRecord를 얻기위해선 QueryListener를 사용해야 한다. 위의 소스는 단지 Query에 이용되는 fullname(serviceName+regType+domain = min_test._min._tcp.local.)인자가 무엇인지 확인한다.

를 얻는다

 

 

멀티라인의 txtRecord를 얻기위해

QueryListener를  (queryAnswered ) 사용하여 아래값을 얻는다.

 ID=cozy--
NAME=min
AGE=26
COR=Gluesys

 

 

자세한 내용은 javadoc을 참고 한다.

 

 

 

  • 오픈소스 JBonjourBrowser 스샷

 

다운 로드 : https://wiki.cs.columbia.edu/display/res/JBonjourBrowser

BonjourBrowser와 다르게 service Type으로 묶어서 표시한다.

 



[참고]

avahi service type 확인

http://linux.die.net/man/5/avahi.service

 

DNSSD javadoc

https://developer.apple.com/library/mac/documentation/Java/Reference/DNSServiceDiscovery_JavaRef/com/apple/dnssd/DNSSD.html

 

Bonjour browser download

http://hobbyistsoftware.com/bonjourbrowser

 


posted by cozyboy
: