1

バンドルの内部でこの問題に直面しています。それをFooBundleServerSocketと呼びましょう。

このFooBundleには、特にSocketListener.javaクラスがあります。このクラスは Thread です。その概要を少し説明するために、いくつかの擬似コードを貼り付けます。

public class SocketListener implements Runnable{

ServerSocket providerSocket;
Socket connection = null;
private boolean closeIt = false;

   public void run() {
        try {
            //Create the server socket
            providerSocket = new ServerSocket(41000, 10);
        } catch (IOException e1) {
            //catching the exception....
        }
        while(!closeIt){
        try{
            connection = providerSocket.accept();
            in = new Scanner(new InputStreamReader(onnection.getInputStream()));
            while(in.hasNext() !=false) 
                    message = message + " "+in.next();
              // bla bla bla...
            } catch (IOException e) {
              //bla bla...
            }
        finally{
         try{
              if (message.equalsIgnoreCase("bye"))
                  providerSocket.close();
                          closeIt = true;
             }
       catch(IOException ioException){
        //........
         }
}

ご覧のとおり、これはSocketClientsの 1 つから受信したメッセージが"bye"になるまで接続を待機する単純なスレッドです。

これは私が今直面している問題です: バンドルが停止した場合、 OSGi フレームワーク全体を再起動する必要があります: バンドルを再起動しようとすると、 「アドレスは既に使用されています」というメッセージがスローされます。そのため、バンドルを停止しましたが、ソケットは閉じられていません。java.net.BindException

stop()OSGi では、メソッド内のメソッドに何をActivator含める必要があるかを考慮する必要がありますが、匿名スレッドの参照をアクティベーターに渡すことはできません。

これがバンドル内の私のクラス図であると想像してください:

**FooBundle**
|__FooBundleActivator
|__FooImpl
|__SocketListener (thread)

スレッドはクラスから匿名スレッドSocketListenerとして呼び出されます。FooImpl

私の質問は次のとおりです。OSGiパラダイム内で、匿名スレッド、特に私の場合、閉じていないソケットポートをそのように制御する適切な方法はありますか?

前もって感謝します。

4

3 に答える 3

2

ServerSocket を外部 (おそらくアクティベーター内) でインスタンス化し、コンストラクターを介して SocketListener に渡します。Activator の stop 関数で serverSocket.stop() を呼び出すことができます。

ServerSocket.stop() を呼び出すと、IOException のサブクラスである SocketException がスローされます。while イテレーションで確実にイテレーションの実行を停止するように IOException を処理することを考えてください。

于 2013-05-21T16:42:38.523 に答える
1

スレッド関数を終了する前に、メッセージに関係なく、リッスンしているソケットを閉じる必要があります。次に、実際に違いを生むのはsetReuseAddress(true)、そのソケットで呼び出して、古い接続がタイムアウト状態でハングしている間にポートをバインドできるようにすることです。

そして、どうぞ、コードでより良いインデント手法を使用してください...

于 2013-05-21T15:55:32.683 に答える