Pre*_*sen 5 java android client-server jmdns dns-sd
我正在构建一个 Java 服务器应用程序(在 PC 上运行),该应用程序使用JmDNS将自身注册到本地网络,以及一个应该使用Network Service Discovery发现 java 服务器的 Android 客户端应用程序。
\n当我先运行android应用程序,然后运行java服务器时,应用程序成功发现注册的java服务器。
\n但是,当我第一次运行服务器,然后运行 Android 应用程序时,onDiscoveryStarted调用了该方法,但该onServiceFound方法从未触发 - Android 应用程序没有发现服务器。\n这在我看来是一个意想不到的行为。
成功案例:
\nAndroid应用程序日志:
\n08-24 22:42:06.157 NSD_DISCOVER onCreate
\n08-24 22:42:06.373 NSD_DISCOVER\xef\xb9\x95 onDiscoveryStarted 服务发现已启动
\n08-24 22:42:30.256 NSD_DISCOVER\ xef\xb9\x95 onServiceFound 已知服务类型:_http._tcp。
\n08-24 22:42:30.293 NSD_DISCOVER\xef\xb9\x95 onServiceResolved 解决成功。名称:NsdApp,类型:._http._tcp,主机:/10.0.0.2,端口:52288
Java 服务器日志:
\nSTART
\n已注册
\nEND
\nWAITING_FOR_MESSAGE
\nhello world
\nEND_THREAD
失败案例:
\n\nAndroid 应用程序日志:
\n08-24 22:05:21.690 NSD_DISCOVER\xef\xb9\x95 onCreate
\n08-24 22:05:21.908 NSD_DISCOVER\xef\xb9\x95 onDiscoveryStarted 服务发现已启动
Java 服务器日志:
\nSTART
\n已注册
\nEND
\nWAITING_FOR_MESSAGE
服务器代码
\n\npublic class Server {\n\n public static String mServiceName = "NsdApp";\n public static final String SERVICE_TYPE = "_http._tcp.local";\n\n static ServerSocket mServerSocket;\n\n\n public static void main(String[] args) throws IOException {\n\n System.out.println("START");\n\n try {\n mServerSocket = new ServerSocket(0);\n } catch (IOException e) {\n System.out.println("ServerSocket(0) FAILED");\n }\n\n int mPort = mServerSocket.getLocalPort();\n\n JmDNS jmdns = JmDNS.create();\n ServiceInfo info = ServiceInfo.create(SERVICE_TYPE, mServiceName, mPort, "B");\n jmdns.registerService(info);\n\n System.out.println("REGISTERED");\n\n jmdns.close();\n\n Thread mReceiveMessage = new Thread(new ReceiveMessage());\n mReceiveMessage.start();\n\n System.out.println("END");\n}\n\npublic static class ReceiveMessage implements Runnable {\n\n public void run() {\n System.out.println("WAITING_FOR_MESSAGE");\n try {\n\n Socket clientSocket = mServerSocket.accept(); \n InputStreamReader inputStreamReader = new InputStreamReader(clientSocket.getInputStream());\n BufferedReader bufferedReader = new BufferedReader(inputStreamReader); \n String message = bufferedReader.readLine();\n System.out.println(message);\n\n bufferedReader.close();\n inputStreamReader.close();\n clientSocket.close();\n System.out.println("END_THREAD");\n\n } catch (IOException ex) {\n System.out.println("Problem in message reading");\n }\n }\n}\n}\nRun Code Online (Sandbox Code Playgroud)\n\n客户端代码
\n\npublic class MainActivity extends Activity {\n\npublic static final String TAG = "NSD_DISCOVER";\npublic static final String SERVICE_TYPE = "_http._tcp.";\nNsdManager.DiscoveryListener mDiscoveryListener;\nNsdManager.ResolveListener mResolveListener;\nNsdManager mNsdManager;\nint port;\nInetAddress host;\n\n\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.activity_main);\n\n Log.v(TAG, "onCreate");\n\n mNsdManager = (NsdManager) getSystemService(Context.NSD_SERVICE);\n initializeResolveListener();\n initializeDiscoveryListener();\n mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);\n}\n\n\npublic void initializeDiscoveryListener() {\n mDiscoveryListener = new NsdManager.DiscoveryListener() {\n\n @Override\n public void onDiscoveryStarted(String regType) {\n Log.v(TAG, "onDiscoveryStarted Service discovery started");\n }\n\n @Override\n public void onServiceFound(NsdServiceInfo service) {\n if (!service.getServiceType().equals(SERVICE_TYPE)) {\n Log.v(TAG, "onServiceFound Unknown Service Type: " + service.getServiceType());\n } else {\n Log.v(TAG, "onServiceFound Known Service Type: " + service.getServiceType());\n mNsdManager.resolveService(service, mResolveListener);\n }\n }\n\n @Override\n public void onServiceLost(NsdServiceInfo service) {\n Log.e(TAG, "service lost" + service);\n }\n\n @Override\n public void onDiscoveryStopped(String serviceType) {\n Log.i(TAG, "Discovery stopped: " + serviceType);\n }\n\n @Override\n public void onStartDiscoveryFailed(String serviceType, int errorCode) {\n Log.e(TAG, "Discovery failed: Error code:" + errorCode);\n mNsdManager.stopServiceDiscovery(this);\n }\n\n @Override\n public void onStopDiscoveryFailed(String serviceType, int errorCode) {\n Log.e(TAG, "Discovery failed: Error code:" + errorCode);\n mNsdManager.stopServiceDiscovery(this);\n }\n };\n}\n\n\npublic void initializeResolveListener() {\n mResolveListener = new NsdManager.ResolveListener() {\n\n @Override\n public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {\n Log.e(TAG, "onResolveFailed Resolve failed" + errorCode);\n }\n\n @Override\n public void onServiceResolved(NsdServiceInfo serviceInfo) {\n Log.v(TAG, "onServiceResolved Resolve Succeeded. " + serviceInfo);\n port = serviceInfo.getPort();\n host = serviceInfo.getHost();\n\n SendMessage sendMessageTask = new SendMessage();\n sendMessageTask.execute();\n }\n };\n}\n\n\nprivate class SendMessage extends AsyncTask<Void, Void, Void> {\n\n @Override\n protected Void doInBackground(Void... params) {\n try {\n\n Socket client;\n PrintWriter printwriter;\n\n client = new Socket(host, port); \n printwriter = new PrintWriter(client.getOutputStream(), true);\n printwriter.write("hello world"); \n\n printwriter.flush();\n printwriter.close();\n client.close(); \n\n } catch (UnknownHostException e) {\n e.printStackTrace();\n } catch (IOException e) {\n e.printStackTrace();\n }\n return null;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n}
\njmdns.close()您注册后立即致电。只有当您打开 jmdns 时,您的服务才能被发现。您应该删除对 的调用close,使您的jmdns变量成为您的类的成员,然后仅当您不希望您的服务再被发现时才调用 close 。另外,在关闭 jmdns 之前调用也是一种很好的形式unregisterAllServices()。
| 归档时间: |
|
| 查看次数: |
1926 次 |
| 最近记录: |