使用common-net.jar中的TelnetClient来模拟一个telnet客户端登录和执行命令。
TelnetClient.getInputStream()获取的输入流,利用它的read方法读取时是可能陷入等待。ReadInformation.readTelnet()方法获取同步锁时,如果陷入输入流的read等待,整个程序就无法进行下去了。我想把这个输入流包装成非阻塞的,不知道能不能实现?哪位高手有其它的解决方法给指点一二,在这先谢过了!
代码如下:import org.apache.commons.net.telnet.*;   
  
import java.io.*;   
import java.net.SocketException;   
import java.util.StringTokenizer;   
  
public class TmhTelnet implements TelnetNotificationHandler {   
  
    private static TelnetClient tc = null;   
    private static InputStream instr;   
    private static PrintWriter out;
    public static void main(String args[]) throws IOException{ 
     TmhTelnet telnet = new TmhTelnet("127.0.0.1",23);  
        ReadInformation readInfo = new ReadInformation("command.txt",instr,out);
        ReadFileThread rfthread = new ReadFileThread(readInfo);
        ReadTelnetThead rtthread = new ReadTelnetThead(readInfo);
        Thread rtt = new Thread(rtthread);
        rtt.start();
        Thread rft = new Thread(rfthread);
        rft.start();
        System.out.println("return");

    }   
    public TmhTelnet(String host, int port) {   
        intconnect(host,port);
    }   
  
    private boolean intconnect(String host, int port) {   
        try {   
            tc = 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);   
  
            tc.addOptionHandler(ttopt);   
            tc.addOptionHandler(echoopt);   
            tc.addOptionHandler(gaopt); 
            tc.connect(host, port);   
            instr = tc.getInputStream();  
            out = new PrintWriter(tc.getOutputStream());   
            return true;   
        } catch (Exception e) {   
            e.printStackTrace();   
            try {   
                tc.disconnect();   
            } catch (IOException e1) {   
                // TODO Auto-generated catch block   
                e1.printStackTrace();   
            }   
            return false;   
        }          
    }   
       
    public void receivedNegotiation(int negotiation_code, int option_code) {   
        String command = null;   
        if (negotiation_code == TelnetNotificationHandler.RECEIVED_DO) {   
            command = "DO";   
        } else if (negotiation_code == TelnetNotificationHandler.RECEIVED_DONT) {   
            command = "DONT";   
        } else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WILL) {   
            command = "WILL";   
        } else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WONT) {   
            command = "WONT";   
        }   
        System.out.println("Received " + command + " for option code "  
                + option_code);   
    }   
} public class ReadFileThread implements Runnable {
private ReadInformation rf = null;
public ReadFileThread(ReadInformation rf){
this.rf = rf;

} public void run() {
while(true){
rf.readFile();
}

}
}public class ReadTelnetThead implements Runnable{
private ReadInformation rf = null;
public ReadTelnetThead(ReadInformation rf){
this.rf = rf;

} public void run() {
while(true){
rf.readTelnet();
}

}
} import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

public class ReadInformation {
private String filename;
private InputStream input;
private PrintWriter pw;
private BufferedReader readCommand = new BufferedReader(new InputStreamReader(System.in));
private BufferedReader br = null;
Integer i = 1;
public ReadInformation(String filename,InputStream input,PrintWriter pw) throws FileNotFoundException{
this.filename = filename;
this.input = input;
this.pw = pw;
br = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
}

public synchronized void readFile(){
try {
String line = br.readLine();
if(i%2==1)
   this.wait();
if(line!=null&&!"".equals(line)){
pw.println(line);
pw.flush();
System.out.println(line);
System.out.println("*******************");
}
else{
line=readCommand.readLine();
if(line==null ||"".equals(line)){
pw.println("\r\n");
pw.flush();
System.out.println("输入指定为空,请输入指令。");
}
else{
pw.println(line);
pw.flush();
System.out.println(line);
System.out.println("*******************");
}

}
Thread.sleep(100);
i++;
this.notify();

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public synchronized void readTelnet(){
        try {   
           
            byte[] buff = new byte[4096];   
            int ret_read = 0;
            if(i%2==0)
             this.wait();
            if((ret_read=input.read(buff)) >= 0)
            { 
                if (ret_read > 0) {
                 Charset charset = Charset.forName("GB18030");
                 //创建解码器(CharsetDecoder)对象
         CharsetDecoder decoder = charset.newDecoder();
         //使用解码器将ByteBuffer转换成CharBuffer
         ByteBuffer by = ByteBuffer.allocate(4096);
         by.put(buff,0,ret_read);
         by.limit(by.position());
         by.position(0);
         CharBuffer charBuffer =  decoder.decode(by);
                    System.out.print(charBuffer); 
                    System.out.println("##################");
                }
            }
            this.notify();
            i++;
        } catch (Exception e) {   
            System.err.println("Exception while reading socket:"  
                    + e.getMessage());   
        } 
}

}
command.txt:
administrator
123

解决方案 »

  1.   

    你好!
    我想读取的是telnent服务器返回的内容,ReadInformation.readTelnet方法获取同步锁时,执行到ret_read=input.read(buff)如果没有读取到任何内容的话,就会陷入等待,那么整个程序就行不下去了。我想如果把input改成非阻塞的,获取同步锁时如果没有读取到任何内容,程序还会继续进行下去。不知道我表述明白了没有?
      

  2.   

    还是得把从telnet服务器返回的消息中的控制字符和颜色字符去掉,然后判断结束的字符是否是">",":"等telnet命令的结束字符。
      

  3.   

    想到个办法,用PushbackInputStream包装system.in,总在缓冲区留一个字符,就可以实现不阻塞输入流了,不知道行不行,我试试