问题描述
我建立使用。结果
当我第一次运行Android应用程序,然后运行Java服务器,应用程序成功地发现了registerd Java服务器。结果
但是当我第一次运行该服务器,然后在Android应用程序,叫做 onDiscoveryStarted
的方法,但 onServiceFound
方法不会触发 - Android应用程序不会发现该服务器。
这似乎是我作为一个意外的行为。
I'm building a Java server application (running on a pc) that register itself to the local network using JmDNS, and an Android client App that should discover the java server using Network Service Discovery.
When I run the android app first, and then run the java server, the app succeed to discover the registerd java server.
But when I first run the server and then the android app, the onDiscoveryStarted
method called but the onServiceFound
method never triggered - the android app doesn't discover the server.This seems to me as an unexpected behavior.
成功案例:结果
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解决成功。名称:NsdApp,类型:._http._tcp,主持人:/10.0.0.2,端口:52288
Succeed case:
Android app log:
08-24 22:42:06.157 NSD_DISCOVER onCreate
08-24 22:42:06.373 NSD_DISCOVER﹕ onDiscoveryStarted Service discovery started
08-24 22:42:30.256 NSD_DISCOVER﹕ onServiceFound Known Service Type: _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服务器日志:结果
START结果
REGISTERED结果
END结果
WAITING_FOR_MESSAGE结果
世界您好结果
END_THREAD
Java server log:
START
REGISTERED
END
WAITING_FOR_MESSAGE
hello world
END_THREAD
失败案例
Android应用程序日志:结果
08-24 22:05:21.690 NSD_DISCOVER:结果的onCreate
08-24 22:05:21.908 NSD_DISCOVER:onDiscoveryStarted服务发现启动
Android app log:
08-24 22:05:21.690 NSD_DISCOVER﹕ onCreate
08-24 22:05:21.908 NSD_DISCOVER﹕ onDiscoveryStarted Service discovery started
Java服务器日志:结果
START结果
REGISTERED结果
END结果
WAITING_FOR_MESSAGE
Java server log:
START
REGISTERED
END
WAITING_FOR_MESSAGE
服务器code
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");
}
}
}
}
客户端code
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;
@Override
protected 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它,当你不希望你的服务能够被发现了。此外,它是很好的形式来调用 unregisterAllServices()
收盘前jmdns。
You are calling jmdns.close()
right after registering. Your service is only discoverable as long as you have jmdns open. You should remove that call to close
, make your jmdns
variable a member of your class, and then only call close on it when you don't want your services to be discoverable anymore. Also, it is good form to call unregisterAllServices()
before closing jmdns.
这篇关于使用网络服务发现Java服务器和Android客户端之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!