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

📄 telnetio.java

📁 java telnet 服务器实现 .
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
//License/*** * Java TelnetD library (embeddable telnet daemon) * Copyright (c) 2000-2005 Dieter Wimberger  * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. *   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE. ***/package net.wimpi.telnetd.io;import net.wimpi.telnetd.net.Connection;import net.wimpi.telnetd.net.ConnectionData;import net.wimpi.telnetd.net.ConnectionEvent;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.InetAddress;/** * Class that represents the TelnetIO implementation. It contains * an inner IACHandler class to handle the telnet protocol level * communication. * <p/> * Although supposed to work full-duplex, we only process the telnet protocol * layer communication in case of reading requests from the higher levels. * This is the only way to meet the one thread per connection requirement. * </p> * <p/> * The output is done via byte-oriented streams, definately suitable for the * telnet protocol. The format of the  output is UTF-8 (Unicode), which is a * standard and supported by any telnet client, including the ones included * in Microsoft OS's. * </p> * <em>Notes:</em> * <ul> * <li>The underlying output is buffered, to ensure that all bytes written * are send, the flush() method has to be called. * <li>This low-level routines ensure nice multithreading behaviour on I/O. * Neither large outputs, nor input sequences excuted by the connection thread * can hog the system. * </ul> * * @author Dieter Wimberger * @version 2.0 (16/07/2006) */public class TelnetIO {  private static Log log = LogFactory.getLog(TelnetIO.class);  private Connection m_Connection;			//a reference to the connection this instance works for  private ConnectionData m_ConnectionData;	//holds all important information of the connection  private DataOutputStream m_Out;		//the byte oriented outputstream  private DataInputStream m_In;			//the byte oriented input stream  //Aggregations  private IACHandler m_IACHandler;					//holds a reference to the aggregated IACHandler  //Members  private InetAddress m_LocalAddress;				//address of the host the telnetd is running on  private boolean m_NOIAC = false;				//describes if IAC was found and if its just processed  private boolean m_Initializing;  private boolean m_CRFlag;  /**   * Creates a TelnetIO object for the given connection.<br>   * Input- and OutputStreams are properly set and the primary telnet   * protocol initialization is carried out by the inner IACHandler class.<BR>   */  public TelnetIO() {  }//constructor  public void initIO() throws IOException {    //we make an instance of our inner class    m_IACHandler = new IACHandler();    //we setup underlying byte oriented streams    m_In = new DataInputStream(m_ConnectionData.getSocket().getInputStream());    m_Out =        new DataOutputStream(new BufferedOutputStream(m_ConnectionData.getSocket().getOutputStream()));    //we save the local address (necessary?)    m_LocalAddress = m_ConnectionData.getSocket().getLocalAddress();    m_CRFlag = false;    //bootstrap telnet communication    initTelnetCommunication();  }//initIO  public void setConnection(Connection con) {    m_Connection = con;    m_ConnectionData = m_Connection.getConnectionData();  }//setConnection  /**** Implementation of OutputStream ****************************************************/  /**   * Method to output a byte. Ensures that CR(\r) is never send   * alone,but CRLF(\r\n), which is a rule of the telnet protocol.   *   * @param b Byte to be written.   */  public void write(byte b)      throws IOException {    //try {    //ensure CRLF(\r\n) is written for LF(\n) to adhere    //to the telnet protocol.    if (!m_CRFlag && b == 10) {      m_Out.write(13);    }    //ensure CRLF(\r\n) is written for CR(\r) to adhere    //to the telnet protocol.    if (m_CRFlag && b != 10) {      m_Out.write(10);    }    m_Out.write(b);    if (b == 13) {      m_CRFlag = true;    } else {      m_CRFlag = false;    }    //} catch (IOException e) {    //  if (m_Connection.isActive()) {    //    m_ConnectionData.getManager().registerBrokenConnection(m_Connection);    //  }    //}  }//write(byte)  /**   * Method to output an int.   *   * @param i Integer to be written.   */  public void write(int i)      throws IOException {    write((byte) i);  }//write(int)  /**   * Method to write an array of bytes.   *   * @param sequence byte[] to be written.   */  public void write(byte[] sequence) throws IOException {    for (int z = 0; z < sequence.length; z++) {      write(sequence[z]);    }  }//write(byte[])  /**   * Method to output an array of int' s.   *   * @param sequence int [] to write   */  public void write(int[] sequence) throws IOException {    for (int j = 0; j < sequence.length; j++) {      write((byte) sequence[j]);    }  }//write(int[])  /**   * Method to write a char.   *   * @param ch char to be written.   */  public void write(char ch) throws IOException {    write((byte) ch);  }//write(char)  /**   * Method to output a string.   *   * @param str String to be written.   */  public void write(String str) throws IOException {    write(str.getBytes());  }//write(String)  /**   * Method to flush all buffered output.   */  public void flush() throws IOException {    //try {    m_Out.flush();    //} catch (IOException e) {    //  if (m_Connection.isActive()) {    //    m_ConnectionData.getManager().registerBrokenConnection(m_Connection);    //  }    //}  }//flush  /**   * Method to close the underlying output stream to free system resources.<br>   * Most likely only to be called by the ConnectionManager upon clean up of   * connections that ended or died.   */  public void closeOutput() {    try {      //sends telnetprotocol logout acknowledgement      write(IAC);      write(DO);      write(LOGOUT);      //and now close underlying outputstream      m_Out.close();    } catch (IOException ex) {      log.error("closeOutput()", ex);      //handle?    }  }//close  private void rawWrite(int i) throws IOException {    //try {    m_Out.write(i);    //} catch (IOException e) {    //  if (m_Connection.isActive()) {    //    m_ConnectionData.getManager().registerBrokenConnection(m_Connection);    //  }    //}  }//rawWrite  /**** End implementation of OutputStream ***********************************************/  /**** Implementation of InputStream ****************************************************/  /**   * Method to read a byte from the InputStream.   * Invokes the IACHandler upon IAC (Byte=255).   *   * @return int read from stream.   */  public int read() throws IOException {    int c = rawread();    //if (c == 255) {    m_NOIAC = false;    while ((c == 255) && (!m_NOIAC)) {      /**       * Read next, and invoke       * the IACHandler he is taking care of the rest. Or at least he should :)       */      c = rawread();      if (c != 255) {        m_IACHandler.handleC(c);        c = rawread();      } else {        m_NOIAC = true;      }    }    return stripCRSeq(c);  }//read  /**   * Method to close the underlying inputstream to free system resources.<br>   * Most likely only to be called by the ConnectionManager upon clean up of   * connections that ended or died.   */  public void closeInput() {    try {      m_In.close();    } catch (IOException e) {      //handle?    }  }//closeInput  /**   * This method reads an unsigned 16bit Integer from the stream,   * its here for getting the NAWS Data Values for height and width.   */  private int read16int() throws IOException {    //try {    int c = m_In.readUnsignedShort();    return c;    /*} catch (EOFException e) {      if (m_Connection.isActive()) {        m_ConnectionData.getManager().registerBrokenConnection(m_Connection);      }      //for the sanity of the compiler we return something      return -2;    } catch (IOException e) {      if (m_Connection.isActive()) {        m_ConnectionData.getManager().registerBrokenConnection(m_Connection);      }      //for the sanity of the compiler we return something      return -1;    }    */  }//read16int  /**   * Method to read a raw byte from the InputStream.<br>   * Telnet protocol layer communication is filtered and processed here.   *   * @return int read from stream.   */  private int rawread() throws IOException {    int b = 0;    //try {    b = m_In.readUnsignedByte();    m_ConnectionData.activity();    return b;    /*    } catch (EOFException e) {        //this means the stream came to an end we can let the        //ConnectionManager do his job.        if (m_Connection.isActive()) {          //log.debug("Registering broken connection " + m_Connection.toString() + " active=" + m_Connection.isActive());          m_ConnectionData.getManager().registerBrokenConnection(m_Connection);        }        //for the sanity of the compiler we return something        return -1;      } catch (IOException e) {        //this also means that the stream is buggy or something        //going wrong. By definition we react the same as in above case        if (!m_Initializing && m_Connection.isActive()) {          //log.debug("Registering broken connection " +          //    m_Connection.toString() + " active=" + m_Connection.isActive() +          //    " initializing=" + m_Initializing);          m_ConnectionData.getManager().registerBrokenConnection(m_Connection);        }        //for the sanity of the compiler we return something        return -1;      }      */  }//rawread  /**   * Checks for the telnet protocol specified  CR followed by NULL or LF<BR>   * Subsequently reads for the next byte and forwards   * only a ENTER represented by LF internally.   */  private int stripCRSeq(int input) throws IOException {    if (input == 13) {      rawread();      return 10;    }    return input;  }//stripCRSeq  /**** Implementation of InputStream ****************************************************/  /****   * Following methods implement init/request/answer procedures for telnet   * protocol level communication.   */  /**   * Method that initializes the telnet communication layer.   */  private void initTelnetCommunication() {    m_Initializing = true;    try {      //start out, some clients just wait      if (m_ConnectionData.isLineMode()) {        m_IACHandler.doLineModeInit();        log.debug("Line mode initialized.");      } else {        m_IACHandler.doCharacterModeInit();        log.debug("Character mode initialized.");      }      //open for a defined timeout so we read incoming negotiation      m_ConnectionData.getSocket().setSoTimeout(1000);      read();         } catch (Exception e) {      //handle properly      //log.error("initTelnetCommunication()",e);    } finally {      //this is important, dont ask me why :)      try {        m_ConnectionData.getSocket().setSoTimeout(0);      } catch (Exception ex) {        log.error("initTelnetCommunication()",ex);

⌨️ 快捷键说明

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