首页 > 关于关闭ServerSocket的一些困惑?

关于关闭ServerSocket的一些困惑?

由于ServerSocket.accept是一个阻塞函数,所以服务器Socket得放在一个新的线程中以免阻塞UI线程。这个新的线程我是用Handler和HandlerThread新建的。而这个新的线程是放在服务里面创建的。最初我是把关闭ServerSoket函数放在finally里面,在测试的时候,我先是开启了服务器Socket,没有连接的时候我就unbindService,然后在service的onDestroy回调中用handler.getLooper().quit()来关闭线程,可是我发现这样无法关闭线程,因为accept是阻塞的,所以quit()这个消息不会被处理,线程自然不会被关闭,finally里面的close也不会执行。于是第二次我把ServerSocket作为service里面的一个全局变量,在onDestroy里关闭线程之前,先close掉serverSocket,这样accept函数会退出,线程自然也能关闭了,但不好的事情发生了,之前的造作完成后,UI县城被阻塞了,ddms里显示main线程的状态变成了Runnable,这我就不懂了,我只是在主线程关闭了serverSocket,并且关闭了用于serverSocket监听连接的线程,但是怎么会阻塞掉UI线程呢?忘大神解惑!
主要代码如下:

 @Override
    public void onCreate() {
        super.onCreate();
        manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        channel = manager.initialize(this,getMainLooper(),null);
        wifiReceiver = new WiFiDirectBroadcastReceiver(this);

        registerReceiver(wifiReceiver,getIntentFilter());

        setEndAccept(false);
        HandlerThread server = new HandlerThread("wifi_server");
        server.start();
        serverAccept = new Handler(server.getLooper(),this);

        //open server socket
        serverAccept.obtainMessage(OPEN_SERVER,-1,-1,null).sendToTarget();
        //startServerSocket = new OpenServerSocket();
        //serverAccept.post(startServerSocket);
    }

 @Override
    public boolean handleMessage(Message message) {
       switch (message.what) {
           case OPEN_SERVER:
               openServerSocket();
               break;
           case OPEN_READING:
               startReading();
               break;
       }
        message.recycle();
        return true;
    }

/**
     *  create and open a server socket
     */
    private void openServerSocket() {
        try {
            if(serverSocket == null) {
                serverSocket = new ServerSocket(port);
            }
            while (!getEndAccept()) {
                Log.e(TAG,"waiting accept ...");
                clientSocket = serverSocket.accept();
                openWorkThread();
            }
        } catch (Exception e) {
            Log.e(TAG,"error in openServerSocket" + e.getMessage(),e);
        }
    }

private void closeServerSocket() {
        if(serverSocket != null && !serverSocket.isClosed()) {
            try {
                serverSocket.close();
            }catch (Exception e) {
                e.printStackTrace();
            }finally {
                serverSocket = null;
            }
        }
    }

 @Override
    public void onDestroy() {
        super.onDestroy();

        if (!getEndAccept()) {
            setEndAccept(true);

            Log.e(TAG,"start to close server thread");

            //close Looper Thread
            closeServerSocket();
            //serverAccept.removeCallbacks(startServerSocket);
            serverAccept.getLooper().quit();

            Log.e(TAG,"end to close server thread");

        }

        wifiReceiver = null;
        channel = null;
        manager = null;
    }

【热门文章】
【热门文章】