我在写SSL通信程序的时候发现,使用DataInputStream的available始终返回零。
根据api文档上的介绍,该类的available方法是调用FilterInputStream的available方法,而FIS的该方法返回InputStream的available值,也就是说总为零。
但是我在使用普通socket的时候DataInputStream的available能正确返回可读的字节数,程序能正常工作。同时我还尝试了BufferedInputStream,该类的available方法是重写过的,但是用在SSLSocket上的时候同样始终返回0。
去掉available判断程序是能正确读取到内容的,但是我需要些一个非阻塞式的程序,直接读取会导致程序阻塞。
请高手给指点一下这究竟是什么原因,或者有没有其他方法可以达到同样的目的
代码如下
代码中因为测试的原因 dis的类型让我改成了BufferedInputStream,原来是DataInputSteam,逻辑是完全一样的。
String keyStore = "d:/keys/clientkey";
String keyPass = "123456";
String trustStore = "d:/keys/clienttrust";
String trustPass = "123456";
SSLSocketFactory ssf = getSSLSocketFactory(keyStore, keyPass,
trustStore, trustPass);
Socket s = ssf.createSocket(
InetAddress.getByName("10.167.228.213"), 9500);
SSLSocket ss = (SSLSocket) s;
ss.startHandshake();
String str = "GET / HTTP/1.1\r\n";
str = str + "Accept: */*\r\n";
str = str + "Accept-Language: ja-JP\r\n";
str = str
+ "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)\r\n";
str = str + "Accept-Encoding: gzip, deflate\r\n";
str = str + "Host: \r\n";
str = str + "Connection: Keep-Alive\r\n";
str = str + "\r\n";
BufferedInputStream dis = new BufferedInputStream(ss.getInputStream());
// BufferedReader bf=new
// BufferedReader(newInputStreamReader(ss.getInputStream()));
DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
BufferedInputStream bis;

dos.write(str.getBytes());
dos.flush();
byte[] data = null;
// long start = System.currentTimeMillis();
// long time = 0;
System.out.println(dis.available());
while (true) {
if (dis.available()> 0) {
byte[] tempdata = new byte[1600];
int charcount = dis.read(tempdata);
if (data == null) {
data = new byte[charcount];
System.arraycopy(tempdata, 0, data, 0, charcount);
} else {
byte[] tempbyte = new byte[data.length + charcount];
System.arraycopy(data, 0, tempbyte, 0, data.length);
System.arraycopy(tempdata, 0, tempbyte, data.length,
charcount);
data = tempbyte;
}
if (charcount < 1600 || dis.available() <= 0) {
 break;
 } }
// time = System.currentTimeMillis() - start;
}
System.out.println(new String(data));

解决方案 »

  1.   

    sslsocket是引用的哪个包呢,是linux下的ssl连接方式的socket连接吗
      

  2.   

    BufferedInputStream的available(),实现上还是调用被BufferedInputStream包装的那个InputStream对象的available()方法,所以是一样的。你可以看看源码。
    一般available()方法都没实现的,貌似也就FileInputStream实现了这个方法。
    jdk api文档也说了,available()是“返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数”,而像socket的话,是网速传输,这个数值是不好估计的,所以没有实现。所以,你最好换个思路去实现你的需求。
      

  3.   

    我也遇到SSLSOcket getInputStream() 阻塞的问题。求解决方法