如何把阻塞输入流包装成非阻塞的?

neunaruto 2010-03-17 02:31:58
使用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
...全文
294 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
suncf1985 2012-10-20
  • 打赏
  • 举报
回复
楼主!你搞定了没有..求解答.遇到同样的问题 求指点 1 2
douniwan5788 2011-11-25
  • 打赏
  • 举报
回复
想到个办法,用PushbackInputStream包装system.in,总在缓冲区留一个字符,就可以实现不阻塞输入流了,不知道行不行,我试试
twinsshehp 2010-09-20
  • 打赏
  • 举报
回复
哥们 你搞定了没。。。。
我也有这个问题
neunaruto 2010-03-18
  • 打赏
  • 举报
回复
还是得把从telnet服务器返回的消息中的控制字符和颜色字符去掉,然后判断结束的字符是否是">",":"等telnet命令的结束字符。
xiesisi3 2010-03-17
  • 打赏
  • 举报
回复
LS就是个悲剧
ladybirds2008 2010-03-17
  • 打赏
  • 举报
回复
ladybirds2008 2010-03-17
  • 打赏
  • 举报
回复
.
.
ladybirds2008 2010-03-17
  • 打赏
  • 举报
回复

.
xiesisi3 2010-03-17
  • 打赏
  • 举报
回复
那么,可以这样,设置等待一段时间,如果超出时间了,那么可以让连接断开,再做你程序的下一步的内容。
也可以如果超出时间,那么另外启动一个线程,把你要执行的代码放进去,不知道这样能帮到你吗
neunaruto 2010-03-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xiesisi3 的回复:]
我不是很明白你的需求,如果你想把阻塞变成非阻塞,那么你想读到些什么呢?
如果你只是程序没办法跑下去,那么用线程就可以了啊。
[/Quote]
你好!
我想读取的是telnent服务器返回的内容,ReadInformation.readTelnet方法获取同步锁时,执行到ret_read=input.read(buff)如果没有读取到任何内容的话,就会陷入等待,那么整个程序就行不下去了。我想如果把input改成非阻塞的,获取同步锁时如果没有读取到任何内容,程序还会继续进行下去。不知道我表述明白了没有?
xiesisi3 2010-03-17
  • 打赏
  • 举报
回复
我不是很明白你的需求,如果你想把阻塞变成非阻塞,那么你想读到些什么呢?
如果你只是程序没办法跑下去,那么用线程就可以了啊。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧