⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 telnetio.java

📁 java telnet 服务器实现 .
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
      }    }    m_Initializing = false;  }//initTelnetCommunication  /**   * Method that represents the answer to the   * AreYouThere question of the telnet protocol specification   * <p/>   * Output of the String [HostAdress:Yes]   */  private void IamHere() {    try {      write("[" + m_LocalAddress.toString() + ":Yes]");      flush();    } catch (Exception ex) {      log.error("IamHere()", ex);    }  }//IamHere  /**   * Network virtual terminal break.   */  private void nvtBreak() {    m_Connection.processConnectionEvent(new ConnectionEvent(m_Connection, ConnectionEvent.CONNECTION_BREAK));  }//nvtBreak  /**   * Method that checks reported terminal sizes and sets the   * asserted values in the ConnectionData instance associated with   * the connection.   *   * @param width  Integer that represents the Window width in chars   * @param height Integer that represents the Window height in chars   */  private void setTerminalGeometry(int width, int height) {    if (width < SMALLEST_BELIEVABLE_WIDTH) {      width = DEFAULT_WIDTH;    }    if (height < SMALLEST_BELIEVABLE_HEIGHT) {      height = DEFAULT_HEIGHT;    }    //DEBUG: write("[New Window Size " + window_width + "x" + window_height + "]");    m_ConnectionData.setTerminalGeometry(width, height);  }//setTerminalGeometry  public void setEcho(boolean b) {  }//setEcho  /**** End telnet protocol level communication methods *******************************/  /**   * An inner class for handling incoming option negotiations implementing the <B>telnet protocol</B>   * specification based upon following Standards and RFCs:   * <OL>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc854.txt">854 Telnet Protocol Specification</A>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc855.txt">855 Telnet Option Specifications</A>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc857.txt">857 Telnet Echo Option</A>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc858.txt">858 Telnet Supress Go Ahead Option</A>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc727.txt">727 Telnet Logout Option</A>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc1073.txt">1073 Telnet Window Size Option</A>   * <LI><A HREF="ftp://ds.internic.net/rfc/rfc1091.txt">1091 Telnet Terminal-Type Option</A>   * </OL>   * <p/>   * Furthermore there are some more, which helped to solve problems, or might be important   * for future enhancements:<BR>   * <A HREF="ftp://ds.internic.net/rfc/rfc1143.txt">1143 The Q Method of Implementing Option Negotiation</A><BR>   * <A HREF="ftp://ds.internic.net/rfc/rfc1416.txt">1416 Telnet Authentication Option</A><BR>   * <p/>   * After an intense study of the available material (mainly cryptical written RFCs,   * a telnet client implementation for the macintosh based upon NCSA telnet, and a server side   * implementation called key, a mud-like system completely written in Java) I realized   * the problems we are facing regarding to the telnet protocol:   * <OL>   * <LI> a minimal spread of invented options, which means there are a lot of invented options,   * but rarely they made it through to become a standard.   * <LI> Dependency on a special type of implementation is dangerous in our case.   * We are no kind of host that offers the user to run several processes at once,   * a BBS is intended to be a single process the user is interacting with.   * <LI> The <B>LAMER</B> has to be expected to log in with the standard Mircosoft telnet   * implementation. This means forget every nice feature and most of the almost-standards.   * <p/>   * </OL>   * <BR>   *   * @author	Dieter Wimberger   * @version	1.1 16/06/1998   * <p/>   * <p/>   * <B>To-Do</B>:<UL>   * <LI>UNIX conform new style TTYPE negotiation. Setting a list and selecting from it...   * </UL>   */  class IACHandler {    /**     * Telnet readin buffer     * Here its implemented guys. Open your eyes upon this solution.     * The others take a one byte solution :)     */    private int[] buffer = new int[2];    /**     * DO_ECHO or not     */    private boolean DO_ECHO = false;    /**     * DO_SUPGA or not     */    private boolean DO_SUPGA = false;    /**     * DO_NAWS or not     */    private boolean DO_NAWS = false;    /**     * DO_TTYPE or not     */    private boolean DO_TTYPE = false;    /**     * DO_LINEMODE or not     */    private boolean DO_LINEMODE = false;    /**     * DO_NEWENV or not     */    private boolean DO_NEWENV = false;    /**     * Are we waiting for a DO reply?     */    private boolean WAIT_DO_REPLY_SUPGA = false;    private boolean WAIT_DO_REPLY_ECHO = false;    private boolean WAIT_DO_REPLY_NAWS = false;    private boolean WAIT_DO_REPLY_TTYPE = false;    private boolean WAIT_DO_REPLY_LINEMODE = false;    private boolean WAIT_LM_MODE_ACK = false;    private boolean WAIT_LM_DO_REPLY_FORWARDMASK = false;    private boolean WAIT_DO_REPLY_NEWENV = false;    private boolean WAIT_NE_SEND_REPLY = false;    /**     * Are we waiting for a WILL reply?     */    private boolean WAIT_WILL_REPLY_SUPGA = false;    private boolean WAIT_WILL_REPLY_ECHO = false;    private boolean WAIT_WILL_REPLY_NAWS = false;    private boolean WAIT_WILL_REPLY_TTYPE = false;    public void doCharacterModeInit() throws IOException {      sendCommand(WILL, ECHO, true);      sendCommand(DONT, ECHO, true); //necessary for some clients      sendCommand(DO, NAWS, true);      sendCommand(WILL, SUPGA, true);      sendCommand(DO, SUPGA, true);      sendCommand(DO, TTYPE, true);      sendCommand(DO, NEWENV, true); //environment variables    }//doCharacterModeInit    public void doLineModeInit() throws IOException {      sendCommand(DO, NAWS, true);      sendCommand(WILL, SUPGA, true);      sendCommand(DO, SUPGA, true);      sendCommand(DO, TTYPE, true);      sendCommand(DO, LINEMODE, true);      sendCommand(DO, NEWENV, true);    }//doLineModeInit    /**     * Method to handle a IAC that came in over the line.     *     * @param i (int)ed byte that followed the IAC     */    public void handleC(int i) throws IOException {      buffer[0] = i;      if (!parseTWO(buffer)) {        buffer[1] = rawread();        parse(buffer);      }      buffer[0] = 0;      buffer[1] = 0;    }//handleC    /**     * Method that parses for options with two characters.     *     * @param buf int [] that represents the first byte that followed the IAC first.     * @return true when it was a two byte command (IAC OPTIONBYTE)     */    private boolean parseTWO(int[] buf) {      switch (buf[0]) {        case IAC:          //doubled IAC to escape 255 is handled within the          //read method.          break;        case AYT:          IamHere();          break;        case AO:        case IP:        case EL:        case EC:        case NOP:          break;        case BRK:          nvtBreak();          break;        default:          return false;      }      return true;    }//parseTWO    /**     * Method that parses further on for options.     *     * @param buf that represents the first two bytes that followed the IAC.     */    private void parse(int[] buf) throws IOException {      switch (buf[0]) {        /* First switch on the Negotiation Option */        case WILL:          if (supported(buf[1]) && isEnabled(buf[1])) {            ;// do nothing          } else {            if (waitDOreply(buf[1]) && supported(buf[1])) {              enable(buf[1]);              setWait(DO, buf[1], false);            } else {              if (supported(buf[1])) {                sendCommand(DO, buf[1], false);                enable(buf[1]);              } else {                sendCommand(DONT, buf[1], false);              }            }          }          break;        case WONT:          if (waitDOreply(buf[1]) && supported(buf[1])) {            setWait(DO, buf[1], false);          } else {            if (supported(buf[1]) && isEnabled(buf[1])) {              // eanable() Method disables an Option that is already enabled              enable(buf[1]);            }          }          break;        case DO:          if (supported(buf[1]) && isEnabled(buf[1])) {            ; // do nothing          } else {            if (waitWILLreply(buf[1]) && supported(buf[1])) {              enable(buf[1]);              setWait(WILL, buf[1], false);            } else {              if (supported(buf[1])) {                sendCommand(WILL, buf[1], false);                enable(buf[1]);              } else {                sendCommand(WONT, buf[1], false);              }            }          }          break;        case DONT:          if (waitWILLreply(buf[1]) && supported(buf[1])) {            setWait(WILL, buf[1], false);          } else {            if (supported(buf[1]) && isEnabled(buf[1])) {              // enable() Method disables an Option that is already enabled              enable(buf[1]);            }          }          break;          /* Now about other two byte IACs */        case DM:	//How do I implement a SYNCH signal?          break;        case SB: //handle subnegotiations          if ((supported(buf[1])) && (isEnabled(buf[1]))) {            switch (buf[1]) {              case NAWS:                handleNAWS();                break;              case TTYPE:                handleTTYPE();                break;              case LINEMODE:                handleLINEMODE();                break;              case NEWENV:                handleNEWENV();                break;              default:                ;            }          } else {            //do nothing          }          break;        default:          ;      }//switch    }//parse    /**     * Method that reads a NawsSubnegotiation that ends up with a IAC SE     * If the measurements are unbelieveable it switches to the defaults.     */    private void handleNAWS() throws IOException {      int width = read16int();      if (width == 255) {        width = read16int(); //handle doubled 255 value;      }      int height = read16int();      if (height == 255) {        height = read16int(); //handle doubled 255 value;      }      skipToSE();      setTerminalGeometry(width, height);    }//handleNAWS    /**     * Method that reads a TTYPE Subnegotiation String that ends up with a IAC SE     * If no Terminal is valid, we switch to the dumb "none" terminal.     */    private void handleTTYPE() throws IOException {      String tmpstr = "";      // The next read should be 0 which is IS by the protocol      // specs. hmmm?      rawread(); //that should be the is :)      tmpstr = readIACSETerminatedString(40);      log.debug("Reported terminal name " + tmpstr);      m_ConnectionData.setNegotiatedTerminalType(tmpstr);    }//handleTTYPE    /**     * Method that handles LINEMODE subnegotiation.     */    public void handleLINEMODE() throws IOException {      int c = rawread();      switch (c) {        case LM_MODE:          handleLMMode();          break;        case LM_SLC:          handleLMSLC();          break;        case WONT:        case WILL:          handleLMForwardMask(c);          break;        default:          //skip to (including) SE          skipToSE();      }    }//handleLINEMODE    public void handleLMMode() throws IOException {      //we sent the default which no client might deny      //so we only wait the ACK      if (WAIT_LM_MODE_ACK) {        int mask = rawread();        if (mask != (LM_EDIT | LM_TRAPSIG | LM_MODEACK)) {          log.debug("Client violates linemodeack sent: " + mask);        }        WAIT_LM_MODE_ACK = false;      }      skipToSE();    }//handleLMMode    public void handleLMSLC() throws IOException {      int[] triple = new int[3];      if (!readTriple(triple)) return;      //SLC will be initiated by the client      //case 1. client requests set      //LINEMODE SLC 0 SLC_DEFAULT 0      if ((triple[0] == 0) && (triple[1] == LM_SLC_DEFAULT) && (triple[2] == 0)) {        skipToSE();        //reply with SLC xxx SLC_DEFAULT 0        rawWrite(IAC);        rawWrite(SB);        rawWrite(LINEMODE);        rawWrite(LM_SLC);        //triples defaults for all        for (int i = 1; i < 12; i++) {          rawWrite(i);          rawWrite(LM_SLC_DEFAULT);          rawWrite(0);        }        rawWrite(IAC);        rawWrite(SE);        flush();      } else {        //case 2: just acknowledge anything we get from the client        rawWrite(IAC);        rawWrite(SB);        rawWrite(LINEMODE);        rawWrite(LM_SLC);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -