使用NIO進行SOCKET通訊,服務端核心代碼如下
@Override public void receiveData()throws IOException{ // TODO Auto-generated method stub recThread = new RecThread(); crtThread =new Thread(recThread); crtThread.start(); } class RecThread implements Runnable{public void run(){try{listen();}catch(IOException e){e.printStackTrace();}}} // 監聽用戶端串連和資料 public void listen() throws IOException { System.out.println("start"); while (threadFlag) { if(threadFlag){ selector.select(); Set<SelectionKey> selectionKeys = selector.selectedKeys(); iterator = selectionKeys.iterator(); while (iterator.hasNext()) { selectionKey = (SelectionKey)iterator.next(); handleKey(); } } } if(selectionKey!=null){ selectionKey.cancel(); } selector.close(); }
然後執行 receiveData() 就可以啟動線程進行監聽,當關閉程式的時候,只需要在 關閉之前將 threadFlag 置為 false 就可以讓線程自動結束
經過測試,我發現:如果用戶端和服務端已經建立串連並且通訊過,那麼用上述的方法可以完全關閉程式,但是
如果只是服務端啟動了監聽線程而沒有用戶端連進來,這時候關閉服務端程式後javaw.exe依然在後台運行,雖然將線程的運行標誌 threadFlag 置為了 false,但很顯然線程依然
在運行,這我就搞不懂了,後來研究了一下發現只要線程代碼裡有 selector.select(); 那麼這個線程就鐵定關不掉,最後實在沒有辦法,使用
Runtime rt = Runtime.getRuntime(); String command = "taskkill /F /IM javaw.exe"; try { rt.exec(command); System.out.println("success closed"); } catch (IOException ex) { ex.printStackTrace(); }
這個很笨的方法徹底關閉了程式……