2012-10-03 101 views
0
到ServerSocket的

我有一個程序我工作在主線程初始化監聽線程監聽到一個ServerSocket傳入連接完全暫停線程監聽用Java

/* 
    * run - this will set up the server so that it is ready to listen. 
    */ 
    public void run(serverVariables servVar, storageManager writer, storageVariables write, CoreVariables coreVar, serverFunctions serv, SQLFunctions SQL, SQLvariables SQLvar, netFunctions conn, netVariables netVar) { 
     ControlFunctions cntrl = new ControlFunctions(); 
     util.doCommand("ifconfig eth0 " + servVar.ip); 
     ListenerThread listen = new ListenerThread(servVar, coreVar, writer, serv, write, SQL, SQLvar, util); 
     try { 
      servVar.servSocket = new ServerSocket(servVar.port); 
      listen.start(); 
      cntrl.getInput(util, clr.YELLOW, SQL, SQLvar, listen, conn, netVar); 
     } catch (IOException e) { 
      System.out.println("Could not read input stream"); 
      e.printStackTrace(); 
     } 
    } 

然後等待從輸入服務器管理員(在cntrl.getInput())。這一切都很好,但我試圖從getInput實現的主要功能是「暫停」,它應該檢查沒有連接,然後停止監聽器和自身。

這裏的監聽線程:

package server; 

import java.io.IOException; 

import net.netFunctions; 
import net.netVariables; 
import core.CoreVariables; 
import utl.utilFunctions; 
import utl.color; 
import server.serverVariables; 
import store.storageManager; 
import store.storageVariables; 
import conn.SQLFunctions; 
import conn.SQLvariables; 

public class ListenerThread extends Thread { 
    color clr = new color(); 
    CoreVariables coreVar = new CoreVariables(); 
    utilFunctions util = new utilFunctions(); 
    netVariables netVar = new netVariables(); 
    storageManager writer = new storageManager(); 
    netFunctions conn = new netFunctions(); 
    storageVariables write = new storageVariables(); 
    serverFunctions serv = new serverFunctions(); 
    serverVariables servVar = new serverVariables(); 
    SQLFunctions SQL = new SQLFunctions(); 
    SQLvariables SQLvar = new SQLvariables(); 
    message msg = new message(); 

    public ListenerThread(serverVariables servVar, CoreVariables coreVar, 
      storageManager writer, serverFunctions serv, 
      storageVariables write, SQLFunctions SQL, SQLvariables SQLvar, 
      utilFunctions util) { 
     super("ListenerThread"); 
     this.coreVar = coreVar; 
     this.util = util; 
     this.writer = writer; 
     this.write = write; 
     this.serv = serv; 
     this.servVar = servVar; 
     this.SQL = SQL; 
     this.SQLvar = SQLvar; 
    } 

    public void run() { 
     util.outColored("Listener thread started", clr.CYAN); 
     while (true) { 
      try { 
       new ConnectionThread(clr.GREEN, servVar.servSocket.accept(), 
         coreVar, util, writer, write, serv, servVar, SQL, 
         SQLvar).start(); 
      } catch (IOException e) { 
       System.out.println("Failed to accept"); 
      } 
     } 
    } 
} 

和haltServer功能:

private boolean haltServer(SQLFunctions SQL, SQLvariables SQLvar, utilFunctions util, String color, ListenerThread listen, netFunctions conn, netVariables netVar) { 
    Socket s = null; 
    boolean success = false; 
    String result = null; 
    int count = 0; 
    //check for open connections 
    SQL.doQuery("SELECT * FROM Clients WHERE Status != 0", SQLvar); 
    try { 
     while(SQLvar.resultSet.next()) { 
      result = SQLvar.resultSet.getString("ClientID"); 
      util.outColored("Client " + result + " is still connected", color); 
      count++; 
     } 
     if(count == 0) { 
      listen.stop(); 
      success = true; 
     } 
     } catch (UnknownHostException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return success; 
} 

我知道,停止計提折舊,並期待在使用所中斷()作爲一個標誌,但我不認爲這將因serverSocket.accept()調用而起作用。

想法?

+0

這是一個常見問題。您應關閉服務器套接字。看到這裏:http://stackoverflow.com/questions/12588476/multithreading-socket-communication-client-server/12589851#12589851 – Gray

+0

也檢查出這個答案:http://stackoverflow.com/questions/5693199/how-does - 多線程服務器工作/ 7572929#7572929 – Gray

+0

謝謝@格雷,我知道這裏有很多信息,但我似乎無法找到一個確鑿和乾淨的答案。 –

回答

2

使用布爾標誌來表示它是否應該打破與否:

private volatile boolean stop = false; 

然後做一個方法叫做像殺(不能停止),其將該標誌設置爲true,則關閉您的ServerSocket :

public voic kill() { 
    stop = true; 
    serverSocket.close(); 
} 

然後,幾乎是在這裏完成的,在代碼接受您的ServerSocket插入插座,在catch塊行了,有這樣的:

try { 
    //accept server socket 
} catch(IOException e) { 
    if(stop) 
     return; 
    e.printStackTrace(); 
} 

因此,關閉ServerSocket時不會打印錯誤,而只是停止嘗試接受連接。最後一件事,改變你的while循環爲:

while(!stop) { ... 

只是爲了確保它正常退出。

其實我有我的電腦關閉Java,它使用下面的代碼上運行的服務器:

threadHandler = new ThreadPoolExecutor(maxThreads, maxThreads, 1, TimeUnit.MINUTES, 
      new ArrayBlockingQueue<Runnable>(maxThreads, true)); 
    while (!serverTerminated) { 
     try { 
      final Socket connectionSocket = serversocket.accept(); 
      SocketHandler handler = new SocketHandler(this, connectionSocket); 
      threadHandler.submit(handler); 
     } catch (IOException e) { 
      if (!serverTerminated) 
       e.printStackTrace(); 
     } 
    } 
+1

我不確定是否可以捕獲一個'IOException'並繼續處理該套接字。 – Gray

+0

@格雷感謝:) –

+0

訣竅,謝謝你的幫助@亞歷克斯曼 –