[英]Odd behavior reading SSL socket Java
我正在尝试使用SSL编写一个简单的echo服务器。 转到服务器的第一行完全回应。 当我发送第二行时,只回显第一个字符。 客户端使用stdin的缓冲读取器读取线。 如果我再次点击CR,则会显示其余信息。 服务器似乎正在发送所有数据。 这是客户端和服务器的输出:
客户:
在端口9999上发送到服务器192.168.0.161
4 seasoNS
回声:4 seasoNS
非常好
回声:一
回声:真的很好
SERVER:服务器监听9999
有cr / lf
4 seasoNS
发送大小:10
有cr / lf
非常好
发送大小:16
退出...
这是客户端循环:
try {
BufferedReader consoleBufferedReader = getConsoleReader();
sslsocket = getSecSocket(strAddress, port);
BufferedWriter sslBufferedWriter = getSslBufferedWriter(sslsocket);
InputStream srvrStream = sslsocket.getInputStream();
String outMsg;
while ((outMsg = consoleBufferedReader.readLine()) != null) {
byte[] srvrData = new byte[1024];
sslBufferedWriter.write(outMsg);
sslBufferedWriter.newLine();
sslBufferedWriter.flush();
int sz = srvrStream.read(srvrData);
String echoStr = new String(srvrData, 0, sz);
System.out.println("echo:" + echoStr);
}
} catch (Exception exception) {
exception.printStackTrace();
}
这个问题看起来很奇怪,我希望有一些明显的东西让我失踪。
你所看到的是完全正常的。
假设您要一次性读取整个缓冲区是错误的:
int sz = srvrStream.read(srvrData);
相反,你需要保持循环,直到你得到你选择的分隔符(在你的情况下可能是一个新的行)。
这通常适用于普通TCP连接以及SSL / TLS连接。 这就是为什么应用程序协议必须具有分隔符或内容长度的原因(例如,HTTP有一个双重新行来结束其标题,并使用Content-Length
或chunked transfer encoding在实体结束时告诉另一方)。
在实践中,您可能看不到何时您的假设不适用于这么小的例子。
但是,JSSE会将它发送的记录拆分为1 / n-1, 以减轻BEAST攻击 。 (OpenSSL将发送0 / n。)因此,在这种情况下,问题更加明显。
同样,这不是SSL / TLS或Java问题,修复此问题的方法是将您读取的输入视为流,而不是假设您在一端读取的缓冲区大小将与用于的缓冲区大小相匹配从另一端发送数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.