TelnetClientExample.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.net.examples.telnet;

  18. import java.io.FileOutputStream;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.OutputStream;
  22. import java.nio.charset.Charset;
  23. import java.time.Duration;
  24. import java.util.StringTokenizer;

  25. import org.apache.commons.net.telnet.EchoOptionHandler;
  26. import org.apache.commons.net.telnet.InvalidTelnetOptionException;
  27. import org.apache.commons.net.telnet.SimpleOptionHandler;
  28. import org.apache.commons.net.telnet.SuppressGAOptionHandler;
  29. import org.apache.commons.net.telnet.TelnetClient;
  30. import org.apache.commons.net.telnet.TelnetNotificationHandler;
  31. import org.apache.commons.net.telnet.TerminalTypeOptionHandler;

  32. /**
  33.  * This is a simple example of use of TelnetClient. An external option handler (SimpleTelnetOptionHandler) is used. Initial configuration requested by
  34.  * TelnetClient will be: WILL ECHO, WILL SUPPRESS-GA, DO SUPPRESS-GA. VT100 terminal type will be subnegotiated.
  35.  * <p>
  36.  * Also, use of the sendAYT(), getLocalOptionState(), getRemoteOptionState() is demonstrated. When connected, type AYT to send an AYT command to the server and
  37.  * see the result. Type OPT to see a report of the state of the first 25 options.
  38.  */
  39. public class TelnetClientExample implements Runnable, TelnetNotificationHandler {
  40.     private static TelnetClient tc;

  41.     /**
  42.      * Main for the TelnetClientExample.
  43.      *
  44.      * @param args input params
  45.      * @throws Exception on error
  46.      */
  47.     public static void main(final String[] args) throws Exception {
  48.         FileOutputStream fout = null;

  49.         if (args.length < 1) {
  50.             System.err.println("Usage: TelnetClientExample <remote-ip> [<remote-port>]");
  51.             System.exit(1);
  52.         }

  53.         final String remoteip = args[0];

  54.         final int remoteport;

  55.         if (args.length > 1) {
  56.             remoteport = Integer.parseInt(args[1]);
  57.         } else {
  58.             remoteport = 23;
  59.         }

  60.         try {
  61.             fout = new FileOutputStream("spy.log", true);
  62.         } catch (final IOException e) {
  63.             System.err.println("Exception while opening the spy file: " + e.getMessage());
  64.         }

  65.         tc = new TelnetClient();

  66.         final TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
  67.         final EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
  68.         final SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);

  69.         try {
  70.             tc.addOptionHandler(ttopt);
  71.             tc.addOptionHandler(echoopt);
  72.             tc.addOptionHandler(gaopt);
  73.         } catch (final InvalidTelnetOptionException e) {
  74.             System.err.println("Error registering option handlers: " + e.getMessage());
  75.         }

  76.         while (true) {
  77.             boolean end_loop = false;
  78.             try {
  79.                 tc.connect(remoteip, remoteport);

  80.                 final Thread reader = new Thread(new TelnetClientExample());
  81.                 tc.registerNotifHandler(new TelnetClientExample());
  82.                 System.out.println("TelnetClientExample");
  83.                 System.out.println("Type AYT to send an AYT telnet command");
  84.                 System.out.println("Type OPT to print a report of status of options (0-24)");
  85.                 System.out.println("Type REGISTER to register a new SimpleOptionHandler");
  86.                 System.out.println("Type UNREGISTER to unregister an OptionHandler");
  87.                 System.out.println("Type SPY to register the spy (connect to port 3333 to spy)");
  88.                 System.out.println("Type UNSPY to stop spying the connection");
  89.                 System.out.println("Type ^[A-Z] to send the control character; use ^^ to send ^");

  90.                 reader.start();
  91.                 final OutputStream outstr = tc.getOutputStream();

  92.                 final byte[] buff = new byte[1024];
  93.                 int readCount = 0;

  94.                 do {
  95.                     try {
  96.                         readCount = System.in.read(buff);
  97.                         if (readCount > 0) {
  98.                             final Charset charset = Charset.defaultCharset();
  99.                             final String line = new String(buff, 0, readCount, charset); // deliberate use of default charset
  100.                             if (line.startsWith("AYT")) {
  101.                                 try {
  102.                                     System.out.println("Sending AYT");

  103.                                     System.out.println("AYT response:" + tc.sendAYT(Duration.ofSeconds(5)));
  104.                                 } catch (final IOException e) {
  105.                                     System.err.println("Exception waiting AYT response: " + e.getMessage());
  106.                                 }
  107.                             } else if (line.startsWith("OPT")) {
  108.                                 System.out.println("Status of options:");
  109.                                 for (int ii = 0; ii < 25; ii++) {
  110.                                     System.out.println("Local Option " + ii + ":" + tc.getLocalOptionState(ii) + " Remote Option " + ii + ":"
  111.                                             + tc.getRemoteOptionState(ii));
  112.                                 }
  113.                             } else if (line.startsWith("REGISTER")) {
  114.                                 final StringTokenizer st = new StringTokenizer(new String(buff, charset));
  115.                                 try {
  116.                                     st.nextToken();
  117.                                     final int opcode = Integer.parseInt(st.nextToken());
  118.                                     final boolean initlocal = Boolean.parseBoolean(st.nextToken());
  119.                                     final boolean initremote = Boolean.parseBoolean(st.nextToken());
  120.                                     final boolean acceptlocal = Boolean.parseBoolean(st.nextToken());
  121.                                     final boolean acceptremote = Boolean.parseBoolean(st.nextToken());
  122.                                     final SimpleOptionHandler opthand = new SimpleOptionHandler(opcode, initlocal, initremote, acceptlocal, acceptremote);
  123.                                     tc.addOptionHandler(opthand);
  124.                                 } catch (final Exception e) {
  125.                                     if (e instanceof InvalidTelnetOptionException) {
  126.                                         System.err.println("Error registering option: " + e.getMessage());
  127.                                     } else {
  128.                                         System.err.println("Invalid REGISTER command.");
  129.                                         System.err.println("Use REGISTER optcode initlocal initremote acceptlocal acceptremote");
  130.                                         System.err.println("(optcode is an integer.)");
  131.                                         System.err.println("(initlocal, initremote, acceptlocal, acceptremote are boolean)");
  132.                                     }
  133.                                 }
  134.                             } else if (line.startsWith("UNREGISTER")) {
  135.                                 final StringTokenizer st = new StringTokenizer(new String(buff, charset));
  136.                                 try {
  137.                                     st.nextToken();
  138.                                     final int opcode = Integer.parseInt(st.nextToken());
  139.                                     tc.deleteOptionHandler(opcode);
  140.                                 } catch (final Exception e) {
  141.                                     if (e instanceof InvalidTelnetOptionException) {
  142.                                         System.err.println("Error unregistering option: " + e.getMessage());
  143.                                     } else {
  144.                                         System.err.println("Invalid UNREGISTER command.");
  145.                                         System.err.println("Use UNREGISTER optcode");
  146.                                         System.err.println("(optcode is an integer)");
  147.                                     }
  148.                                 }
  149.                             } else if (line.startsWith("SPY")) {
  150.                                 tc.registerSpyStream(fout);
  151.                             } else if (line.startsWith("UNSPY")) {
  152.                                 tc.stopSpyStream();
  153.                             } else if (line.matches("^\\^[A-Z^]\\r?\\n?$")) {
  154.                                 final byte toSend = buff[1];
  155.                                 if (toSend == '^') {
  156.                                     outstr.write(toSend);
  157.                                 } else {
  158.                                     outstr.write(toSend - 'A' + 1);
  159.                                 }
  160.                                 outstr.flush();
  161.                             } else {
  162.                                 try {
  163.                                     outstr.write(buff, 0, readCount);
  164.                                     outstr.flush();
  165.                                 } catch (final IOException e) {
  166.                                     end_loop = true;
  167.                                 }
  168.                             }
  169.                         }
  170.                     } catch (final IOException e) {
  171.                         System.err.println("Exception while reading keyboard:" + e.getMessage());
  172.                         end_loop = true;
  173.                     }
  174.                 } while (readCount > 0 && !end_loop);

  175.                 try {
  176.                     tc.disconnect();
  177.                 } catch (final IOException e) {
  178.                     System.err.println("Exception while connecting:" + e.getMessage());
  179.                 }
  180.             } catch (final IOException e) {
  181.                 System.err.println("Exception while connecting:" + e.getMessage());
  182.                 System.exit(1);
  183.             }
  184.         }
  185.     }

  186.     /**
  187.      * Callback method called when TelnetClient receives an option negotiation command.
  188.      *
  189.      * @param negotiation_code - type of negotiation command received (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT, RECEIVED_COMMAND)
  190.      * @param option_code      - code of the option negotiated
  191.      */
  192.     @Override
  193.     public void receivedNegotiation(final int negotiation_code, final int option_code) {
  194.         String command;
  195.         switch (negotiation_code) {
  196.         case TelnetNotificationHandler.RECEIVED_DO:
  197.             command = "DO";
  198.             break;
  199.         case TelnetNotificationHandler.RECEIVED_DONT:
  200.             command = "DONT";
  201.             break;
  202.         case TelnetNotificationHandler.RECEIVED_WILL:
  203.             command = "WILL";
  204.             break;
  205.         case TelnetNotificationHandler.RECEIVED_WONT:
  206.             command = "WONT";
  207.             break;
  208.         case TelnetNotificationHandler.RECEIVED_COMMAND:
  209.             command = "COMMAND";
  210.             break;
  211.         default:
  212.             command = Integer.toString(negotiation_code); // Should not happen
  213.             break;
  214.         }
  215.         System.out.println("Received " + command + " for option code " + option_code);
  216.     }

  217.     /**
  218.      * Reader thread: Reads lines from the TelnetClient and echoes them on the screen.
  219.      */
  220.     @Override
  221.     public void run() {
  222.         final InputStream instr = tc.getInputStream();

  223.         try {
  224.             final byte[] buff = new byte[1024];
  225.             int readCount = 0;

  226.             do {
  227.                 readCount = instr.read(buff);
  228.                 if (readCount > 0) {
  229.                     System.out.print(new String(buff, 0, readCount, Charset.defaultCharset()));
  230.                 }
  231.             } while (readCount >= 0);
  232.         } catch (final IOException e) {
  233.             System.err.println("Exception while reading socket:" + e.getMessage());
  234.         }

  235.         try {
  236.             tc.disconnect();
  237.         } catch (final IOException e) {
  238.             System.err.println("Exception while closing telnet:" + e.getMessage());
  239.         }
  240.     }
  241. }