/**
 * telnet到指定服务器上执行指定命令
 * @author penglili
 */import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;//import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import java.util.Properties;public class TelnetCmd {
   //static final char LF = 10;
   
   static final char LF = 10;
   static final char CR = 13;
   static final char DC1 = 17;
   
 private String host="17.1.2.182";
 private int   port   =   23;
 private   Socket   socket= null;
 
 private  InputStream   is=null;   
 private OutputStream   os=null;   
 private DataInputStream   sin=null;   
 private PrintStream   sout=null;   
 
 private StringBuffer sb =new StringBuffer();
 
 public  TelnetCmd()
 {
  
 }
 public  TelnetCmd(String host,int   port) 
 {
    
      this.host  =host;
      this.port = port;
 }
 public int hand(InputStream   is,   OutputStream   os)   throws   IOException   {   
    while(true)   {   
      int   ch   =   is.read();  
     // System.out.println("Svr[ch]:"   +   ch);
      if(ch==82)
      {
       System.out.println(ch);
      }
      if(ch   <   0   ||   ch   !=   255)   
       return   ch;   
      int   cmd   =   is.read();   
      int   opt   =   is.read();   
      //System.out.println("Svr[cmd&opt]:"   +   cmd+" : "+opt); 
      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);   
            //System.out.println("Svr[while]:"   +   svr); 
            svr   =   is.read();   
           }   
           //System.out.println("Svr:"   +   baos.toString());   
          }   
          os.flush();
          break;   
        default:   
        if   (cmd   ==   253)   {   
         os.write(255);   
         os.write(252);   
         os.write(opt);   
         os.flush();
         //System.out.println("Svr[default]:"   +   opt);
        }   
      }   
    }   
    }  
 public void pause(int cnt) throws InterruptedException 
 { 
     Thread.sleep(cnt);
  /*for(int i=0; i< cnt * 1000000; i++)
  {
   
  }*/
 }
 
 /**
  * 在指定服务器上执行指定命令
  * @param serviceIp 服务器ip
  * @param userName  用户名
  * @param password  密码
  * @param path 路径
  * @param cmd 命令
  * @throws java.io.IOException
  * @throws java.lang.InterruptedException
  */
 public void open(String serviceIp,String userName,String password,String path,String cmd) throws IOException, InterruptedException
 {
   socket   =   new   Socket(serviceIp,   this.port); 
        // System.out.println("client   ok");   
   //获得对应socket的输入/输出流   
       is   =   socket.getInputStream();     
       os   =  socket.getOutputStream();     
       hand(is,os);   
          //输入用户名和密码
          send(userName);
        this.pause(500);
       send(password);
       System.out.println("open :------------1-------------- ");
       System.out.println(receive());
       System.out.println("open :------------1-end ------------- ");
          //执行命令
         String   cdpathStr   =   "cd "+path;       
         send(cdpathStr);   //将读取得字符串传给server   
         System.out.println("open :------------2-------------- ");
         System.out.println(receive());
         System.out.println("open :------------2-end ------------- ");         //执行命令
        // cmd   =   "mkdir -p /dsdata/ods/Dataspace/ods_test/123test/";       
         send(cmd);   //将读取得字符串传给server   
         System.out.println("open :------------3-------------- ");
         System.out.println(receive());
         System.out.println("open :------------3-end ------------- ");
         
      //退出telnet
         logOut();
 }
 
 /**
  * 登出
  * Send data to the remote host.
  * @param buf array of bytes to send
  * @see #receive
  */
  public void logOut() throws IOException {
   //linux
//   String cmdStr="logout"+CR+LF;
//        send(cmdStr.getBytes());
   //windows
   String cmdStr="exit";
        send(cmdStr);
    }
  /**
   * 发送命令
   * @param cmd
   * @throws java.io.IOException
   */ 
     public void send(String cmd) throws IOException {
      String cmdStr = cmd+LF+CR;
      
      os.write(cmdStr.getBytes());
      os.flush();
     }
    
     public void send(byte b) throws IOException {
      System.out.println("Connected   to"+socket.getInetAddress()+":"+   socket.getPort());  
      os.write(b);
      os.flush();
     }
/**
 * 接收返回字符
 * @return
 * @throws java.io.IOException
 * @throws java.lang.InterruptedException
 */
 public String receive() throws IOException, InterruptedException
 {
  String result="";
  String temp=null;
  this.pause(10);
  for(int i=0; i< 2; i++)
  {
   temp = receiveData();
   String des=new String(temp.getBytes(),"UTF-8");
   result += des; 
  }
  return result;
 }
 public String receiveData() throws IOException
 {
    StringBuffer Sb =new StringBuffer();
    BufferedReader   br   =   new   BufferedReader(new   InputStreamReader(is));
    char[]   buf   =   new   char[102400];
    int   read   =   br.read(buf);    
    String temp=null;
    temp = new   String(buf,0,read);
    //System.out.println("receiveData[while] : "+ temp+" :read: "+read);  
       Sb.append(temp);
   return Sb.toString(); 
 } 
 
 public void close() throws IOException
 {
 
   //关闭连接   
        if( sin != null ) sin.close();   //关闭数据输入流   
        if( sout != null ) sout.close();   //关闭数据输出流   
        if( is != null ) is.close();   //关闭数据输入流   
        if( os != null ) os.close();   //关闭数据输出流 
        if( socket != null ) 
        {
         socket.close();   //关闭socket 
        }
 } /**
  * @param penglili
  */
 public static void main(String[] args) throws InterruptedException {
  TelnetCmd telnet = new TelnetCmd();
  try
  {
   telnet.open("17.1.2.182","dsadm","111111","/dsdata/ods/Dataspace/ods_test/","./myshell.sh");
   
   
   telnet.close();
  }
  catch(IOException ie)
  {
   ie.printStackTrace();
   try
   {
    telnet.close();
   }
   catch(IOException iec)
   {
    iec.printStackTrace();
   }
  }
  
 }}这个程序(暂且叫T程序吧)的大致作用就是telnet到远程服务器上,运行指定目录下的程序(暂且叫M程序吧),但是往往程序M还没有运行完毕,T程序就运行完了,怎么改才能使T程序等待M程序运行完毕后再返回呢???请高手赐教。

解决方案 »

  1.   

    建议用java concurrent库来解决这类问题, 设置Condition条件,等待目标线程结束我的新书刚上架,欢迎订购:
    《搜索引擎零距离—基于Ruby+Java搜索引擎原理与实现》 清华出版社。
    http://www.huachu.com.cn/itbook/itbookinfo.asp?lbbh=10105450
      

  2.   

    风马牛不相及。楼主通过telnet到远程主机,是因为没有判断输入流是否读完,而是循环读了两次,这样并不严格,导致对方指令没有读完就退出。
      

  3.   

    楼主,我给你一段代码,是我原来读取telnet输出流的,供你参考:其中,waitForString,是在一定的时常内,等待特定的字符串(通常用于判断提示符是否出现),
    而readAll方法,则是尝试在一定的时间内读取所有的数据,第二个参数表示是否等待足够时长,
    如果为false,则读到输出流中没有数据则返回,如果为true,则无论流中是否有数据,都一直等到第一个参数指定的时长才返回。你可以将你的receive方法,改成
    我的
    readAll(10*1000,false);
    试试public String waitForString(String s, Integer timeout) throws Exception {
    if (this.getInputStream()==null){
    throw new Exception("Can't get input stream, maybe not connected");
    }
    Reader reader=new InputStreamReader(this.getInputStream());
    StringBuffer sb = new StringBuffer();
    if (timeout == null || timeout.intValue() == 0) {
    while (sb.toString().indexOf(s) == -1) {
    sb.append((char) reader.read());
    }
    } else {
    Calendar endTime = Calendar.getInstance();
    endTime.add(Calendar.SECOND, timeout.intValue());
    while (sb.toString().indexOf(s) == -1) {
    while (Calendar.getInstance().before(endTime)
    && !reader.ready()) {
    Thread.sleep(250);
    }
    if (!reader.ready()) {
    logger.debug("Read before running into timeout: "
    + sb.toString());
    throw new Exception("Response timed-out waiting for \"" + s
    + '\"');
    }
    sb.append((char) reader.read());
    }
    }
    return sbToString(sb);
    } /* (non-Javadoc)
     * @see com.ubi.cmdsvr.telnet.RemoteAccessSession#readAll(java.lang.Integer, boolean)
     */
    /* (non-Javadoc)
     * @see com.ubi.cmdsvr.telnet.IRemoteAccessSession#readAll(java.lang.Integer, boolean)
     */
    public String readAll(Integer timeout, boolean waitFullTime) throws Exception{
    if (timeout == null || timeout.intValue() < 0) {
    return "";
    }
    if (this.getInputStream()==null){
    throw new Exception("Can't get input stream, maybe not connected");
    }
    Reader reader=new InputStreamReader(this.getInputStream());
    StringBuffer sb=new StringBuffer();
    Calendar endTime = Calendar.getInstance();
    endTime.add(Calendar.SECOND, timeout.intValue());
    while (Calendar.getInstance().before(endTime)) {
    if (!reader.ready()){
    Thread.sleep(250);
    }
    if (!reader.ready()){
    if (waitFullTime || StringUtils.isBlank(sb.toString())){
    continue;
    }else{
    break;
    }
    }
    char curChar=(char) reader.read();

    if (curChar=='\r'){
    continue;
    }
    sb.append(curChar);
    }
    return sbToString(sb);
    }
      

  4.   

    jinxfei ,能把你的程序全贴出来吗?有很多方法都没有定义,比如this.getInputStream()、 StringUtils.isBlank(sb.toString())等。