关于available方法,read()方法会出现 阻塞问题

wendenryyy 2013-08-05 04:29:29
今天测试telnet登陆遇到一个奇怪的问题:
加入while (in.available() > 0) {} 判断时,谁在方法in.available()时阻塞。请教各位大神,available方法本身不是个阻塞的方法,在什么情况下会出现这样的问题?


private boolean waitForLoginFinish() throws IOException
{
StringBuffer sb = new StringBuffer();
char ch;
long start=System.currentTimeMillis() ;
System.out.println("start start");
while(System.currentTimeMillis() - start < timeout){

int i = -1;
while (in.available() >= 0) {
//long s=System.currentTimeMillis() ;
//while(System.currentTimeMillis() - s < 10000){
i=in.read();
if(i == -1) {
return false;
}
ch = (char) i;
sb.append(ch);
System.out.println(sb.toString());
if (sb.indexOf(prompt) != -1) {
return true;
}else if(sb.indexOf(env.getLoginSuccPrompt())!=-1){
return false;
}else {
try {
//这里是防止网络慢的时候,in.available()经常为0,导致大量循环引起过多的indexOf
Thread.sleep(100);
} catch (Exception e) {}
}
}
System.out.println("end read");
}
return false;


如下为输入结果,如果将
while (in.available() >= 0) {
替换为:
long s=System.currentTimeMillis() ;
while(System.currentTimeMillis() - s < 10000){
就没有问题,另外,有没有好的方法可以解决read阻塞的问题.......

start start
+
++
+++
lgi:op="EMS\\xxxxxx",pwd="xxxxx!";
invoke arguments,taskId:groovy
com.eastcom.dcmp.probe.common.exception.SessionException: Login failed ! [xxxxxxxxxxxxxxx] , reason :Read timed out
at com.eastcom.dcmp.probe.terminal.sessionImpl.TL2Session.login(TL2Session.java:205)
at com.eastcom.dcmp.probe.common.collect.BaseCollector.loginSession(BaseCollector.java:56)
at com.eastcom.dcmp.script.TaskGroovyExecutor.execute(TaskGroovyExecutor.java:59)
at com.eastcom.dcmp.script.test.TestTerminalGroovy.testGroovy5(TestTerminalGroovy.java:62)
at com.eastcom.dcmp.script.test.TestTerminalGroovy.testGroovy(TestTerminalGroovy.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
...全文
234 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
小行星0906 2013-08-05
  • 打赏
  • 举报
回复
引用 楼主 wendenryyy 的回复:
今天测试telnet登陆遇到一个奇怪的问题: 加入while (in.available() > 0) {} 判断时,谁在方法in.available()时阻塞。请教各位大神,available方法本身不是个阻塞的方法,在什么情况下会出现这样的问题?
哥,不是很懂,但是你要对流进行操作就修改流的读取方法吧,我能想到的,才学习到流这里,要想除掉=0时候还要循环一次才出来-1的话,只能写自己的流读取方法。 教程给的草例:
public class MyOwnStream2 extends InputStream
{
	protected byte[] data;

	protected int ptr = 0;// 读取到的位置

	private int mark = 0;// 标记位置

	public MyOwnStream2(byte[] b)
	{
		this.data = b;
	}

	@Override
	public int read() throws IOException
	{
		return ptr < data.length ? data[ptr++] : -1;
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException
	{
		if (this.ptr >= data.length || len < 0)
		{
			return -1;
		}

		if (this.ptr + len > data.length)
		{
			len = data.length - this.ptr;
		}

		if (len == 0)
		{
			return 0;
		}

		System.arraycopy(data, ptr, b, off, len);

		ptr += len;

		return len;
	}

	/**
	 * 剩余未读的长度
	 */
	@Override
	public int available() throws IOException
	{
		return data.length - ptr;
	}

	/**
	 * 关闭,简单实现使读取位置等于文件长度
	 */
	@Override
	public void close() throws IOException
	{
		ptr = data.length;
	}

	/**
	 * 标记位置,下次可以跳到这个位置
	 */
	@Override
	public synchronized void mark(int readlimit)
	{
		this.mark = readlimit;
	}

	/**
	 * 跳回标记位置
	 */
	@Override
	public synchronized void reset() throws IOException
	{
		if (mark < 0 || mark > data.length)
		{
			throw new IOException("the position is not valid");
		}
		ptr = mark;
	}

	/**
	 * 是否支持标记,这里强制可以
	 */
	@Override
	public boolean markSupported()
	{
		return true;
	}

}
oh_Maxy 2013-08-05
  • 打赏
  • 举报
回复
while (in.available() > 0) 等于0,就应该跳出循环了吧

62,614

社区成员

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

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