整个代码都很复杂,所以我直接说到了这一点.代码如下
SSLContext ctx = SSLContext.getInstance("TLS");
Run Code Online (Sandbox Code Playgroud)
如果你读了getInstance(字符串协议)方法的文档,它说
This method traverses the list of registered security Providers, starting
with the most preferred Provider. A new SSLContext object encapsulating
the SSLContextSpi implementation from the first Provider that supports the
specified protocol is returned.
Note that the list of registered providers may be retrieved via the
Security.getProviders() method.
Run Code Online (Sandbox Code Playgroud)
For me Security.getProviders() method gives following providers

Now I have verified that "TLS" protocol is in com.sun.net.ssl.internal.ssl.Provider (index 2 ) and is always selected.
But the corresponding SSLContextSpi object is coming different in Java 6 and Java 7. In java 6 I am getting com.sun.net.ssl.internal.ssl.SSLContextImpl@7bbf68a9 and in java 7 I am getting sun.security.ssl.SSLContextImpl$TLS10Context@615ece16. This is having very bad effect as when later I am creating SSL socket they are of different class.
So why is this happening? Is there a work around? I want the same com.sun.net.ssl.internal.ssl.SSLContextImpl@7bbf68a9 SSLContextSpi object encapsulated in com.sun.net.ssl.internal.ssl.Provider context(which is same in both cases).
这有非常糟糕的效果,因为稍后我创建SSL套接字时它们属于不同的类.
这不是一个坏的影响.您从公共API中的工厂获得的实际课程由JRE实施决定:这些具体类不是公共API的一部分.
您在Java 6和Java 7之间获得不同类的事实并不重要.即使它们具有相同的名称,如果将它们相互比较也没有意义.
编辑:
public int read(byte[] b)当我给它一个长度为4的字节数组时,函数只读取1个字节,并且我已经确认流中有4个字节.
SSLSocket在Java 7中,当你得到它时,它的行为是正确的.事实上,它可能表现得更好,因为这个初始的1字节读取是由于BEAST预防措施.我将复制并粘贴我自己的答案,因为你犯了完全相同的错误.
你在读取与byte[]在另一端写入它们完全相同的假设是一个典型的TCP错误.它实际上并不特定于SSL/TLS,但也可能发生TCP连接.
在TCP(以及SSL/TLS)中无法保证读取器的缓冲区将填充与写入器缓冲区中的数据包完全相同的数据包长度.所有TCP保证都是按顺序交付,因此您最终将获得所有数据,但您必须将其视为流.
这就是使用TCP的协议依赖于指示符和分隔符来告诉另一端何时停止读取某些消息的原因.
例如,HTTP 1.1使用空行来指示标题何时结束,并使用Content-Length标头告诉收件人期望的实体长度(或分块传输编码).SMTP还使用行返回和.消息的结尾.
如果您正在设计自己的协议,则需要为收件人定义一种方法,以便知道何时定义为有意义的数据单元.读取数据时,请阅读此类指示符,并填写读取缓冲区,直到获得预期的字节数或找到已定义的分隔符.
| 归档时间: |
|
| 查看次数: |
7381 次 |
| 最近记录: |