我正在构建一个Java服务器应用程序(在PC上运行),它使用JmDNS将自己注册到本地网络,以及一个应该使用Network Service Discovery发现java服务器的AndroID客户端应用程序.
当我首先运行AndroID应用程序,然后运行java服务器时,应用程序成功发现注册的java服务器.
但是当我第一次运行服务器然后运行AndroID应用程序时,ondiscoveryStarted方法被调用但是onServiceFound方法从未被触发 – androID应用程序没有发现服务器.
这在我看来是一种意想不到的行为.
成功案例:
AndroID应用日志:
08-24 22:42:06.157 NSD_disCOVER onCreate
08-24 22:42:06.373 NSD_disCOVER:ondiscoveryStarted服务发现已启动
08-24 22:42:30.256 NSD_disCOVER:onServiceFound已知服务类型:_http._tcp.
08-24 22:42:30.293 NSD_disCOVER:onServiceResolved Resolve Succeeded. name:NsdApp,type:._ http._tcp,host:/10.0.0.2,port:52288
Java服务器日志:
开始
注册
结束
WAITING_FOR_MESSAGE
你好,世界
END_THREAD
失败案例:
AndroID应用日志:
08-24 22:05:21.690 NSD_disCOVER:onCreate
08-24 22:05:21.908 NSD_disCOVER:ondiscoveryStarted服务发现开始了
Java服务器日志:
开始
注册
结束
WAITING_FOR_MESSAGE
服务器代码
public class Server { public static String mServicename = "NsdApp"; public static final String SERVICE_TYPE = "_http._tcp.local"; static ServerSocket mServerSocket; public static voID main(String[] args) throws IOException { System.out.println("START"); try { mServerSocket = new ServerSocket(0); } catch (IOException e) { System.out.println("ServerSocket(0) Failed"); } int mPort = mServerSocket.getLocalPort(); JmDNS jmdns = JmDNS.create(); ServiceInfo info = ServiceInfo.create(SERVICE_TYPE, mServicename, mPort, "B"); jmdns.registerService(info); System.out.println("REGISTERED"); jmdns.close(); Thread mReceiveMessage = new Thread(new ReceiveMessage()); mReceiveMessage.start(); System.out.println("END");}public static class ReceiveMessage implements Runnable { public voID run() { System.out.println("WAITING_FOR_MESSAGE"); try { Socket clIEntSocket = mServerSocket.accept(); inputStreamReader inputStreamReader = new inputStreamReader(clIEntSocket.getinputStream()); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String message = bufferedReader.readline(); System.out.println(message); bufferedReader.close(); inputStreamReader.close(); clIEntSocket.close(); System.out.println("END_THREAD"); } catch (IOException ex) { System.out.println("Problem in message reading"); } }}}
客户代码
public class MainActivity extends Activity {public static final String TAG = "NSD_disCOVER";public static final String SERVICE_TYPE = "_http._tcp.";NsdManager.discoveryListener mdiscoveryListener;NsdManager.ResolveListener mResolveListener;NsdManager mNsdManager;int port;InetAddress host;@OverrIDeprotected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); Log.v(TAG, "onCreate"); mNsdManager = (NsdManager) getSystemService(Context.NSD_SERVICE); initializeResolveListener(); initializediscoveryListener(); mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCol_DNS_SD, mdiscoveryListener);}public voID initializediscoveryListener() { mdiscoveryListener = new NsdManager.discoveryListener() { @OverrIDe public voID ondiscoveryStarted(String regType) { Log.v(TAG, "ondiscoveryStarted Service discovery started"); } @OverrIDe public voID onServiceFound(NsdServiceInfo service) { if (!service.getServiceType().equals(SERVICE_TYPE)) { Log.v(TAG, "onServiceFound UnkNown Service Type: " + service.getServiceType()); } else { Log.v(TAG, "onServiceFound KNown Service Type: " + service.getServiceType()); mNsdManager.resolveService(service, mResolveListener); } } @OverrIDe public voID onServiceLost(NsdServiceInfo service) { Log.e(TAG, "service lost" + service); } @OverrIDe public voID ondiscoveryStopped(String serviceType) { Log.i(TAG, "discovery stopped: " + serviceType); } @OverrIDe public voID onStartdiscoveryFailed(String serviceType, int errorCode) { Log.e(TAG, "discovery Failed: Error code:" + errorCode); mNsdManager.stopServicediscovery(this); } @OverrIDe public voID onStopdiscoveryFailed(String serviceType, int errorCode) { Log.e(TAG, "discovery Failed: Error code:" + errorCode); mNsdManager.stopServicediscovery(this); } };}public voID initializeResolveListener() { mResolveListener = new NsdManager.ResolveListener() { @OverrIDe public voID onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { Log.e(TAG, "onResolveFailed Resolve Failed" + errorCode); } @OverrIDe public voID onServiceResolved(NsdServiceInfo serviceInfo) { Log.v(TAG, "onServiceResolved Resolve Succeeded. " + serviceInfo); port = serviceInfo.getPort(); host = serviceInfo.getHost(); SendMessage sendMessageTask = new SendMessage(); sendMessageTask.execute(); } };}private class SendMessage extends AsyncTask<VoID, VoID, VoID> { @OverrIDe protected VoID doInBackground(VoID... params) { try { Socket clIEnt; PrintWriter printwriter; clIEnt = new Socket(host, port); printwriter = new PrintWriter(clIEnt.getoutputStream(), true); printwriter.write("hello world"); printwriter.flush(); printwriter.close(); clIEnt.close(); } catch (UnkNownHostException e) { e.printstacktrace(); } catch (IOException e) { e.printstacktrace(); } return null; }}
}
解决方法:
您在注册后立即调用jmdns.close().只要您打开jmdns,您的服务才能被发现.您应该删除该调用以关闭,使您的jmdns变量成为您的类的成员,然后只在您不希望您的服务被发现时才调用close.此外,在关闭jmdns之前调用unregisterallServices()是一种很好的形式.
总结以上是内存溢出为你收集整理的使用网络服务发现在Java服务器和Android客户端之间进行通信全部内容,希望文章能够帮你解决使用网络服务发现在Java服务器和Android客户端之间进行通信所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)