今天测试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)
加入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)
等于0,就应该跳出循环了吧
哥,不是很懂,但是你要对流进行操作就修改流的读取方法吧,我能想到的,才学习到流这里,要想除掉=0时候还要循环一次才出来-1的话,只能写自己的流读取方法。教程给的草例:
public class MyOwnStream2 extends InputStream
{
protected byte[] data; protected int ptr = 0;// 读取到的位置 private int = 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 (int readlimit)
{
this. = readlimit;
} /**
* 跳回标记位置
*/
@Override
public synchronized void reset() throws IOException
{
if ( < 0 || > data.length)
{
throw new IOException("the position is not valid");
}
ptr = ;
} /**
* 是否支持标记,这里强制可以
*/
@Override
public boolean Supported()
{
return true;
}}