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
'학습자료 > Java' 카테고리의 다른 글
[Java] messagePack(rpc 구현) (0) | 2013.02.27 |
---|---|
[java] Java decompiler[Eclipse plugin] (0) | 2013.02.26 |
[Java] Network framework (Netty, Apache MINA) (0) | 2013.02.26 |
자바 정규식 문법 [펌] (0) | 2012.08.14 |
자바 anntation @SuppressWarnings [펌] (0) | 2012.08.14 |