Wal*_*ter 1 java sockets ssl bufferedinputstream
使用Java 7和SSL套接字时,我遇到了一个令人费解的问题.
我有一个客户端/服务器包.两者都使用非常简单的协议相互发送XML数据.每条消息的前4个字节始终包含整个消息的长度.这意味着,它是XML数据的长度加上4个字节.
首先,客户端向服务器发送问候消息.接下来,服务器解释问候语并发送响应.然后,客户端自己解释该消息并发送其登录信息.服务器检查该信息并发回响应.但是这一次,客户端没有收到任何东西,尽管它使用与从服务器获取问候响应时相同的方法.
这是客户端的简化阅读方法:
private String readResponse() throws Exception
{
BufferedInputStream inputBuffer = new BufferedInputStream(sslSocket.getInputStream());
// Read and interprete the first 4 bytes to get the length of the XML-data
int messageLength = readMessageLength(inputBuffer) - 4;
// PROBLEM OCCURS HERE!
// Read bufferSize bytes from stream
byte[] byteArray = new byte[messageLength];
inputBuffer.read(byteArray);
// Return the XML-data
return new String(byteArray);
}
Run Code Online (Sandbox Code Playgroud)
这里是从前4个字节中检索长度的方法......
private int readMessageLength(BufferedInputStream in) throws IOException {
byte[] b = new byte[4];
in.read(b, 0, 4);
return (((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16) | ((b[2] & 0xff) << 8) | (b[3] & 0xff));
}
Run Code Online (Sandbox Code Playgroud)
在客户端应该读取第二个响应时,inputBuffer仅包含零([0, 0, 0, 0, 0, 0, ...]).因此,当尝试使用时计算消息长度时readMessageLength(),它会返回-4.当然,这会导致异常.
似乎很明显,服务器发送的数据尚未准备好被客户端读取.因此,我做了一些改变:
int messageLength;
do {
messageLength = readMessageLength(inputBuffer) - 4;
} while(messageLength <= 0);
Run Code Online (Sandbox Code Playgroud)
但是,这也不起作用.现在出现了令人费解的部分:发生的事情是这个循环执行了两次!分配给messageLength现在的值来自XML数据的前4个字节.read-method返回的字符串现在以缺少的?xml地方开头<!
所以,我尝试标记并重置第一个字节:inputBuffer.mark(4);
int messageLength;
do {
inputBuffer.reset();
messageLength = readMessageLength(inputBuffer) - 4;
} while(messageLength <= 0);
Run Code Online (Sandbox Code Playgroud)
但这实际上是一个无休止的循环.由于inputBuffer永不改变的内容,messageLength永远不会成为别的东西-4.
我何时可以确定发送给客户的数据是否可用?我该怎么检查?什么是更好的方法?
此致,沃尔特
PS可用方法()没有用,因为在使用SSL套接字时它似乎总是返回零.
绝对必须始终检查从通信通道读取的字节数.它有时也可能为零,在这种情况下你必须继续阅读.仅使用负返回值达到流结束.
具体而言,in.read(新字节[100])将不必然读取100个字节.
如果你想保证你得到了所有东西,你需要使用readFully.
| 归档时间: |
|
| 查看次数: |
916 次 |
| 最近记录: |