在使用 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);
}
这里是从前 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));
}
在客户端应读取第二个响应时,inputBuffer
仅包含零 ( [0, 0, 0, 0, 0, 0, ...]
)。因此,当尝试使用 计算消息长度时readMessageLength()
,它会返回-4
. 当然,这会导致一个例外。
服务器发送的数据似乎还没有准备好被客户端读取。因此,我做了一些改变:
int messageLength;
do {
messageLength = readMessageLength(inputBuffer) - 4;
} while(messageLength <= 0);
然而,这也没有奏效。现在是令人费解的部分:发生的情况是这个循环执行了两次!现在分配给的值messageLength
来自 XML 数据的前 4 个字节。读取方法返回的字符串现在以 开头?xml
,其中<
缺少 !
所以,我尝试标记并重置第一个字节: inputBuffer.mark(4);
int messageLength;
do {
inputBuffer.reset();
messageLength = readMessageLength(inputBuffer) - 4;
} while(messageLength <= 0);
但这实际上是一个无限循环。由于inputBuffer
永远不会改变的内容,messageLength
永远不会变成-4
.
我什么时候可以确定发送给客户端的数据可用?我怎么能检查呢?什么可能是更好的方法?
问候,沃尔特
PS available() 方法没有用,因为在使用 SSL 套接字时它似乎总是返回零。