本文介绍了使用网络服务发现Java服务器和Android客户端之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立使用。结果
当我第一次运行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客户端之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 08:58
查看更多