我写了程序实现TELNET,有握手的过程,如下:
 import   java.io.*;   
  import   java.net.Socket;   
    
  public   class   TelnetExample   {  
///TELNET握手过程 
  public   static   int   hand(InputStream   is,   OutputStream   os)   throws   IOException   {   
  while(true)   {   
  int   ch   =   is.read();   
  if(ch   <   0   ||   ch   !=   255)   
  return   ch;   
  int   cmd   =   is.read();   
  int   opt   =   is.read();   
  switch(opt)   {   
  case   1: //   echo协商选项,本程序未处理   
  break;   
  case   3: //   supress   go-ahead(抑制向前选项)   
  break;     
  case   24: //   terminal   type(终端类型选项)   
  if(cmd   ==   253)   {   
  os.write(255);   
  os.write(251);   
  os.write(24);   
    
  os.write(255);   
  os.write(250);   
  os.write(24);   
  os.write(0);   
  os.write("dumb".getBytes());   
  os.write(255);   
  os.write(240);   
  }   else   if   (cmd   ==   250)   {   
  ByteArrayOutputStream   baos   =   new   ByteArrayOutputStream();   
  int   svr   =   is.read();   
  while(svr   !=   240)   {   
  baos.write(svr);   
  svr   =   is.read();   
  }   
  System.out.println("Svr:"   +   baos.toString());   
  }   
  break;   
  default:   
  if   (cmd   ==   253)   {   
  os.write(255);   
  os.write(252);   
  os.write(opt);   
  }   
  }   
  }   
  }   
  public   static   void   main(String[]   args)   throws   Exception   {   
  Socket   s   =   new   Socket("host",23);   
  InputStream   is   =   s.getInputStream();   
  OutputStream   os   =   s.getOutputStream();   
  System.out.println(hand(is,os));  //TELNET握手 
    
  os.write("user\n".getBytes());   
  os.write("password\n".getBytes());   
  BufferedReader   br   =   new   BufferedReader(new   InputStreamReader(is));   
  char[]   buf   =   new   char[1024];   
  int   read   =   br.read(buf);     
  while(read   >   0)   {   
  System.out.println(new   String(buf,0,read));   
  read   =   br.read(buf);   
  }   
  }   
  }   
TELNET登录是成功了,但是发一些指令比如:ps -ef,却发现回送过来的信息(收到什么就显示什么)常有一些奇怪的字符,而这些字符在实际的TELNET中应该是不可见的,而且信息的分割很乱,如何做的跟TELNET中的回显一模一样呢(即过滤了那些不可见字符同时又分行显示),请赐教,万分感谢。分不是问题。

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【newyu1127】截止到2008-07-07 17:11:29的历史汇总数据(不包括此帖):
    发帖的总数量:22                       发帖的总分数:1970                     
    结贴的总数量:18                       结贴的总分数:1570                     
    无满意结贴数:1                        无满意结贴分:100                      
    未结的帖子数:4                        未结的总分数:400                      
    结贴的百分比:81.82 %               结分的百分比:79.70 %                  
    无满意结贴率:5.56  %               无满意结分率:6.37  %                  
    楼主加油
      

  2.   

    我有一个完整的telnet的程序,不知道怎么发给你。留下你QQ吧
      

  3.   

    不懂,帮不了你,没鼓捣过不过你可以参考 http://commons.apache.org/net/已经有现成的类库实现了各种常见的协议,我们何必自己写一个呢?如果为了研究,可以参考他的源代码。
      

  4.   

    是下载commons-net-1.4.1.jar吗?这个要怎么建TELNET客户端呢?
      

  5.   

    有现成的telnet工具吧?叫telnetd。我一直用
    搂住可以看看源代码研究
      

  6.   

    看了commons-net-1.4.1.jar的例子,照着写了一个如下:
    import org.apache.commons.net.telnet.*;
    import java.io.*;
    import java.net.SocketException;
    import java.util.StringTokenizer;
    public class TelnetSample {
        private TelnetClient telnet = null;
        private InputStream in;
        private PrintStream out;
        private char prompt = '#';    public TelnetSample(String server, String user, String password) {
            try {
                // Connect to the specified server
                telnet = new TelnetClient();
                TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler(
                        "VT100", false, false, true, false);
                EchoOptionHandler echoopt = new EchoOptionHandler(true, false,
                        true, false);
                SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true,
                        true, true, true);            telnet.addOptionHandler(ttopt);
                telnet.addOptionHandler(echoopt);
                telnet.addOptionHandler(gaopt);            telnet.connect(server, 23);            // Get input and output stream references
                in = telnet.getInputStream();
                out = new PrintStream(telnet.getOutputStream());            // Log the user on
                readUntil("login: ");
                write(user);            readUntil("Password: ");
                write(password);            // Advance to a prompt
                readUntil(prompt + " ");        } catch (Exception e) {
                e.printStackTrace();
            }
        }
       public String readUntil(String pattern) {
            try {
                char lastChar = pattern.charAt(pattern.length() - 1);
                StringBuffer sb = new StringBuffer();
                boolean found = false;
                int k = in.read();
                char ch = (char) k;
                while (true) {
       
                        System.out.print(ch);
                        sb.append(ch);
                        if (ch == lastChar) {
                            if (sb.toString().endsWith(pattern)) {
                                return sb.toString();
                            }
                        }                k = in.read();
                    ch = (char) k;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }    public void write(String value) {
            try {
                out.println(value);
                out.flush();
                System.out.println(value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }    public String sendCommand(String command) {
            try {
                prompt = '#';
                write(command);
                return readUntil(prompt + " ");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }    public void disconnect() {
            try {
                telnet.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }    public static void main(String[] args) {
            try {
                TelnetSample telnet = new TelnetSample("192.168.0.1",
                        "USERNAME",
                        "PASSWORD");
                telnet.sendCommand("ls -la");
                telnet.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    可以实现TELNET,但问题还是一样,执行"top"这样的指令时,仍然如:
    # top
    top
    [?25h78System: inmsTue Jul  8 13:59:24 2008
    Load averages: 0.08, 0.11, 0.10
    289 processes: 194 sleeping, 73 running, 22 zombies
    Cpu states:
    CPU   LOAD   USER   NICE    SYS   IDLE  BLOCK  SWAIT   INTR   SSYS
     0    0.10   1.0%   1.0%   2.0%  96.0%   0.0%   0.0%   0.0%   0.0%
     1    0.09   1.0%   0.0%   2.0%  97.1%   0.0%   0.0%   0.0%   0.0%
     2    0.07   1.0%   0.0%   2.9%  96.1%   0.0%   0.0%   0.0%   0.0%
     3    0.08   5.9%   0.0%   3.9%  90.2%   0.0%   0.0%   0.0%   0.0%
    ---   ----  -----  -----  -----  -----  -----  -----  -----  -----
    avg   0.08   2.9%   0.0%   2.9%  94.1%   0.0%   0.0%   0.0%   0.0%
    Memory: 2987056K (2400640K) real, 6322408K (5643224K) virtual, 557556K free  Pag
    e# 
    有[?25h78[这样的非法字符显示出来,而且结果也与正常的TELNET结果不同少了很多.
    一查原因是收到'#'字符时就中断读取了,怎么解决这两个问题???
      

  7.   

    其实最核心的问题就一个:实现TELNET的时候怎么避免那些
    [?25h78[这样的非法字符显示出来?!!!
      

  8.   

    网上有很多java实现的开源telnet客户端.楼主可以去找找看/
      

  9.   

    上面的例子就是照网上的例子写的,就是无法避免那些 
    [?25h78[这样的非法字符显示出来?!!!怎么办?
      

  10.   

    这些代码属于BIG5等类型的代码,我觉得首先要求显示控件能够支持字符的颜色吧!楼主可以查找下BIG5的相关资料
      

  11.   

    因为你在最开始new TelnetClient()的时候没有设置参数,如下所示: 
    private TelnetClient telnet = new TelnetClient(); 
    远程登录AIX、linux、sun 服务器执行脚本返回信息都正常,但远程登录windows执行脚本返回信息是乱码。 后来在new TelnetClient()的时候设置了参数,如下所: 
    private TelnetClient telnet = new TelnetClient("VT220"); 问题解决!
      

  12.   

     1、前景色     
            
      暗色:格式为“*[0;3xm”其中0代表暗色的属性,3x表示31~37的各个值,     
                  分别代表不同的颜色,其中的*号为按两下Esc键打出。举例如下:     
            
                  *[0;30m       黑色       *[0;30;47m测试一下   ==>   测试一下     
                  *[0;31m       红色       *[0;31m测试一下   ==>   测试一下     
                  *[0;32m       绿色       *[0;32m测试一下   ==>   测试一下     
                  *[0;33m     土棕色     *[0;33m测试一下   ==>   测试一下     
                  *[0;34m       深蓝       *[0;34m测试一下   ==>   测试一下     
                  *[0;35m       紫色       *[0;35m测试一下   ==>   测试一下     
                  *[0;36m       浅蓝       *[0;36m测试一下   ==>   测试一下     
                  *[0;37m       白色       *[0;37m测试一下   ==>   测试一下     
            
      亮色:格式为“*[1;3xm”其中1代表亮色的属性,3x表示31~37的各个值,     
                  分别代表不同的颜色,其中的*号为按两下Esc键打出。举例如下:     
            
                  *[1;30m     深灰色     *[1;30m测试一下   ==>   测试一下     
                  *[1;31m     亮红色     *[1;31m测试一下   ==>   测试一下     
                  *[1;32m     亮绿色     *[1;32m测试一下   ==>   测试一下     
                  *[1;33m       黄色       *[1;33m测试一下   ==>   测试一下     
                  *[1;34m     亮深蓝     *[1;34m测试一下   ==>   测试一下     
                  *[1;35m     亮紫色     *[1;35m测试一下   ==>   测试一下     
                  *[1;36m     亮浅蓝     *[1;36m测试一下   ==>   测试一下     
                  *[1;37m     亮白色     *[1;37m测试一下   ==>   测试一下     
            
      2、背景色     
            
      背景色与前景色稍有不同,它不分暗色亮色,所有背景色都是暗色,因此控制符     
      也比较简单,格式是“*[4xm”,其中4x代表从40~47的数值,不同数值所对应的     
      背景色也不同,此外格式中4xm后面可以加空格,空格可表示背景色的范围,结束     
      位置以*[m为标志,先以红色背景为例说明一下:     
            
      *[41m         *[m         ==>     
                ↑↑                           ↑↑     
                一二                           一二     
            
            
      当然这其中的空格若以汉字或其他符号代替也可。下面列举一下各背景色的具体例子:     
            
                *[40m   黑色   *[m     ==>       黑色     
                *[41m   红色   *[m     ==>       红色     
                *[42m   绿色   *[m     ==>       绿色     
                *[43m   棕色   *[m     ==>       棕色     
                *[44m   深蓝   *[m     ==>       深蓝     
                *[45m   紫色   *[m     ==>       紫色     
                *[46m   浅蓝   *[m     ==>       浅蓝     
                *[47m   白色   *[m     ==>       白色     
      

  13.   

      1、闪烁控制符——*[5m     
            这是比较常用的一种控制符,它能使其后面的字符产生闪烁效果,例如:     
            
            *[5m闪烁*[m     ==>       闪烁     
            *[1;5;32m测试一下*[m     ==>     测试一下     
            
            需要注意的是,闪烁控制符在需要结束闪烁的部位一定要加上*[m,否则就会使得     
            闪烁控制符之后的所有符号都闪烁起来,那样效果可就有点乱套了。     
            
      2、下划线——*[4m     
            顾名思义,就是在字符下加一条下划线,例如:     
            
            *[4m   测试一下   *[m     ==>       测试一下     
            *[1;4;32m   测试一下   *[m     ==>       测试一下     
            
            需要说明一点的是老版本的sterm是不支持下画线功能的,现在的1.266版本倒是     
            支持下划线,下划线的颜色和前景色一致,就如上面第二个例子,前景色是绿色     
            所以下划线也是绿色。而使用cterm看到的下划线则无论前景色为什么,一律都为     
            白色。     
            
      3、相反显示——*[7m     
            这个也很容易理解,就是使用这个函数就会将底色和前景色互换,例如:     
            
            *[1;31;43m测试一下*[m     ==>     测试一下     这是黄色背景,红色前景     
            但是加了*[7m之后就会变成     
            *[1;7;31;43m测试一下*[m     ==>     测试一下     这是红色背景,黄色前景     
            
            这个需要说明的也是sterm和cterm略有不同,本来说背景色是没有高亮的,但是sterm     
            1.266版本却有显示高亮背景的本领,就是通过这个相反显示函数,上面例子如果你用     
            sterm1.266版来看得话,你就会发现,那个例子本来是高亮红色前景和低亮的黄色背景     
            但是加了反显函数之后那个例子变成了高亮的红色背景和低亮的黄色前景,就是前景色     
            和背景色完全互换,连亮度也保持一致。但如果用cterm来看得话,就会发现加了反显     
            函数之后的例子是低亮的红色背景和高亮的黄色前景,不但颜色互换,连亮度也互换     
            了,因为cterm无法显示出高亮的背景。     
            
      4、其余的上色控制符     
            
            在不用*[1;3xm这种格式的情况下,bbs里也能在某些符号下给文字上色,现总结如下:     
            
      ①   :号     
      其实就是当你回文章时系统在文章前所加的:号,它会使文章颜色变为暗青色,与*[0;36m     
      效果相同,这个冒号必须是英文输入法状态下的冒号,而且必须处在该行第一的位置,     
      冒号后可以有空格,该符号只对本行内容有效。     
            
      举例如下:     
      :)     
      :   )     
      :                 like   this     
            
      ②【   在………………   】格式     
      同样这种格式也要处在该行的起始位置,效果与*[1;33m的效果相同,【后要空上一个     
      英文字符的位置,那个“在”字不能少,而且必须是第一个字,后面的内容任意。     
      该符号对从此行开始的一屏内所有文字都有效     
            
      举例如下:     
      【   在此一游,MidautumnDay   】     
            
      ③   >号     
      效果和:号完全一样,也是要放在该行的起始位置,>号后面可以不空格,也可以加     
      空格,效果都一样。该符号仅对本行的内容有效。     
            
            
      举例如下:     
      >see?     
      >     就是这样了。     
            
      ④   ==>号     
      效果相当于*[1;33m,位置也要位于该行起始位置,==>后面不需空格,加空格也可     
      该符号对从此开始一屏内的内容均有效     
            
      举例如下:     
      ==>这是例子     
      ==>     see?     
            
      --     
      

  14.   

    参与下:
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;import org.apache.commons.net.telnet.TelnetClient;public class TelnetUtils {
    //telnet客户端对象
    TelnetClient client = new TelnetClient("vt52");
    StringBuffer buffer = new StringBuffer();
    InputStream inputStream = null; //输入流,接收服务端的返回信息
    OutputStream outputStream = null; //输出流,向服务端写命令
    private static List<String> defaultPromt = new ArrayList<String>();
    private static List<String> user = new ArrayList<String>();
    private static List<String> pass = new ArrayList<String>(); static {
    defaultPromt.add("#");
    defaultPromt.add(">");
    user.add("ogin:");
    pass.add("assword:");
    } public static void main(String[] args) throws Exception {
    TelnetUtils a = new TelnetUtils("132.121.162.236", 23, "omc", "gdtelomc");
    // a.sendCommand("whoami");
    // System.out.println(a.getResult());
    a.sendCommand("netstat -in | awk '{print $4}' | grep 172.16.3.27");
    System.out.println("=========");
    String rs = a.getResult();
    System.out.println(rs);
    System.out.println("=========");
    System.out.println(rs.split("\n")[0]);
    a.close();
    } /**
     * @param hostname 服务器IP地址
     * @param port telnet端口
     * @param username 用户名
     * @param password 密码
     * @throws Exception
     */
    public TelnetUtils(String hostname, int port, String username, String password)
    throws Exception {
    //连接服务器
    conn(hostname, port);
    //获得输入流对象
    this.inputStream = this.client.getInputStream();
    //获得输出流对象
    this.outputStream = this.client.getOutputStream();
    login(username, password);
    } /**
     * 关闭连接
     * @throws Exception
     */
    public void close() throws Exception {
    this.client.disconnect();
    } /**
     * 连接到服务器
     * @param hostname 服务器IP地址
     * @param port 端口
     * @throws Exception
     */
    private void conn(String hostname, int port) throws Exception {
    this.client.connect(hostname, port);
    } /**
     * 登录服务器
     * @param username 用户名
     * @param password 密码
     * @throws Exception
     */
    private void login(String username, String password) throws Exception {
    sendCommand(username, user);
    List<String> temp = new ArrayList<String>();
    temp.add(":");
    String result = getResult(temp); if (!(result.trim().endsWith("word:"))) {
    throw new Exception("Invalid user:" + username);
    }
    temp.add("#");
    temp.add(">");
    sendCommand(password, pass);
    result = getResult(temp); if ((result.trim().endsWith("word:"))
    || (result.trim().endsWith("ogin:"))) {
    throw new Exception("Invalid username or password:" + username
    + " " + password);
    }
    } public void sendCommand(String command) throws Exception {
    sendCommand(command, defaultPromt);
    } public String getResult() throws Exception {
    return getResult(defaultPromt);
    } /**
     * 往服务器输入命令
     * @param command 命令指令
     * @param wantedEndString
     * @throws Exception
     */
    public void sendCommand(String command, List<String> wantedEndString)
    throws Exception {
    waitForString(wantedEndString);
    this.buffer.delete(0, this.buffer.length());
    //输出输入的命令值
    // System.out.println(command + "\n");
    this.outputStream.write((command + "\n").getBytes());
    this.outputStream.flush();
    } public String getResult(List<String> endString) throws Exception {
    waitForString(endString);
    return this.buffer.toString();
    } private void waitForString(List<String> wantedEndString) throws Exception {
    int aword = 0;
    boolean matchOne = false;
    while (!(matchOne)) {
    for (int i = 0; i < wantedEndString.size(); ++i) {
    if ((this.buffer.toString().trim()
    .endsWith((String) wantedEndString.get(i)))
    && (this.inputStream.available() == 0)) {
    matchOne = true;
    }
    }
    if (matchOne) {
    return;
    }
    aword = this.inputStream.read();
    // System.out.print((char) aword);
    if (aword < 0) {
    throw new Exception("Connection disconnect...");
    }
    this.buffer.append((char) aword);
    }
    } public boolean isClosed() {
    return (!(this.client.isConnected()));
    }
    }