1

Apache Commons TelnetClientを使用して、一部のスイッチの自動Telnetインターフェイスを作成しています。マシンから直接スイッチにtelnetで接続すると、接続がタイムアウトしないように見えます。ランダムに、Javaプログラムでは、接続はInputStreamとともにすぐに閉じるように見えます。接続の失敗を確認して再接続を試みるチェックを作成しようとしましたが、最初に失敗した場合は常に失敗します。

import org.apache.commons.net.telnet.TelnetClient;

  public String connect()
  {
     String errorMessage = null;
     tcConnectionHandle = new TelnetClient();
     tcConnectionHandle.setDefaultTimeout(iTimeOutMilliseconds);

     try
     {
        tcConnectionHandle.connect(strConnectionIP, intConnectionPort);
        osOutput = tcConnectionHandle.getOutputStream();
        isInput = tcConnectionHandle.getInputStream();
        int availableBytes = isInput.available();

        while(availableBytes <= 0)
        {
           tcConnectionHandle = null;
           isInput = null;
           osOutput = null;
           Thread.sleep(500);
           tcConnectionHandle = new TelnetClient();
           Thread.sleep(500);
           tcConnectionHandle.setDefaultTimeout(iTimeOutMilliseconds);
           Thread.sleep(500);
           tcConnectionHandle.connect(strConnectionIP, intConnectionPort);
           Thread.sleep(500);
           osOutput = tcConnectionHandle.getOutputStream();
           Thread.sleep(500);
           isInput = tcConnectionHandle.getInputStream();
           Thread.sleep(500);
           availableBytes = isInput.available();
           System.out.println("reopened: " + availableBytes);
        }
     }
     catch(InterruptedException iX)
     {
        errorMessage = "Could not establish connection. " + iX.getLocalizedMessage();
     }
     catch(SocketException sX)
     {
        errorMessage = sX.getMessage();
     }
     catch(IOException ioX)
     {
        errorMessage = ioX.getMessage();
     }

     return errorMessage;
  }

省略した場合Thread.sleep(500)、availableBytesはありません。一時停止すると、結果は20になりますが、使用しようとするisInput.read()と-1が返されます。これは、InputStreamが閉じていることを意味します。

接続障害をキャッチして接続を再試行する方法を探しています。頻繁に発生するため、再試行できません。

4

1 に答える 1

1

TelnetClientに接続されたInputStreamはランダムに閉じた状態だったと思います。新しいTelnetClientオブジェクトを作成し、後で同じTelnetサーバーに再接続した場合でも、その状態でそれを読み取ろうとすると、通信が失敗しました。意味がありませんが、TelnetClientクラスで何が起こっているのかを理解するのではなく、新しいアプローチを試すことにしました。

implements TelnetInputListenerこのクラスで使用して問題を解決しました。が呼び出されたときにInputStreamがnullになるtelnetInputAvailable()ことがありますが、関数への特定の呼び出しで何もしないことで、InputStreamから回復できるようになりました。

public String connect()
{
   String errorMessage = null;
   tcConnectionHandle = new TelnetClient();
   tcConnectionHandle.setDefaultTimeout(iTimeOutMilliseconds);
   tcConnectionHandle.registerInputListener(this);

   try
   {
      tcConnectionHandle.connect(strConnectionIP, intConnectionPort);
      osOutput = tcConnectionHandle.getOutputStream();
      isInput = tcConnectionHandle.getInputStream();
   }
   catch(SocketException sX)
   {
      errorMessage = sX.getMessage();
   }
   catch(IOException ioX)
   {
      errorMessage = ioX.getMessage();
   }

   return errorMessage;
}

public Matcher waitForRegularExpression(String regularExpression)
{
   Matcher matcher;
   Pattern pattern = Pattern.compile("(?s)" + regularExpression);
   StringBuilder warningLog = new StringBuilder();

   synchronized(sbInputBuffer)
   {
      matcher = pattern.matcher(sbInputBuffer.toString());

      while(!matcher.find())
      {
         try
         {
            int inputBufferSize = sbInputBuffer.length();
            sbInputBuffer.wait(iTimeOutMilliseconds);

            if(inputBufferSize == sbInputBuffer.length())
            {
               warningLog.append("Did not find pattern and no new input.");
               logWarning(warningLog.toString());
               return null;
            }
         }
         catch(InterruptedException intX)
         {
            warningLog.append("Interrupted waiting on input. ").append(intX.getLocalizedMessage());
         }

         matcher = pattern.matcher(sbInputBuffer.toString());
      }

      sbInputBuffer.delete(0, matcher.end()-1);
   }

   if(!warningLog.toString().isEmpty())
   {
      logWarning(warningLog.toString());
   }

   return matcher;
}

@Override
public void telnetInputAvailable()
{
   synchronized(sbInputBuffer)
   {
      StringBuilder warningLog = new StringBuilder();
      int readBytes = -2;

      if(isInput != null)
      {
         try
         {
            readBytes = isInput.read();

            if(readBytes > 0)
            {
               sbInputBuffer.append((char)readBytes);
            }

            sbInputBuffer.notify();
         }
         catch(IOException ioX)
         {
            warningLog.append("Failed for IO: ").append(ioX.getLocalizedMessage()).append(" - input so far: ")
               .append(sbInputBuffer.toString()).append("\nRead bytes: ").append(readBytes).append("\n");
            logWarning(warningLog.toString());
         }
      }
   }
}
于 2012-08-28T13:47:50.317 に答える