0

メインスレッドがリスナースレッドを初期化してserverSocketへの着信接続をリッスンするプログラムに取り組んでいます

    /*
     * 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;
}

stop が減価償却されていることを認識しており、interupted() をフラグとして使用することを調べましたが、serverSocket.accept() 呼び出しのために機能するとは思いません。

アイデア?

4

1 に答える 1

2

ブールフラグを使用して、破損するかどうかを表します。

private volatile boolean stop = false;

次に、フラグをtrueに設定して、ServerSocketを閉じるkill(停止することはできません)のようなメソッドを作成します。

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();
        }
    }
于 2012-10-03T20:02:27.313 に答える