读取SSL套接字Java的奇怪行为
我正在尝试使用SSL编写一个简单的echo服务器。到达服务器的第一行被准确地回显。当我发送第二行时,只回显第一个字符。客户机从stdin的缓冲读卡器读取行开始工作。如果我再次点击CR,其余的信息就会通过。服务器似乎正在发送所有数据。以下是客户端和服务器的输出: 客户: 发送至192.168.0.161处的服务器 在端口9999上 四季读取SSL套接字Java的奇怪行为,java,ssl,Java,Ssl,我正在尝试使用SSL编写一个简单的echo服务器。到达服务器的第一行被准确地回显。当我发送第二行时,只回显第一个字符。客户机从stdin的缓冲读卡器读取行开始工作。如果我再次点击CR,其余的信息就会通过。服务器似乎正在发送所有数据。以下是客户端和服务器的输出: 客户: 发送至192.168.0.161处的服务器 在端口9999上 四季 回声:四季 你真的很好 回声:a 埃科:你真的很好 服务器: 服务器在9999上侦听 有cr/lf 四季 要发送的大小:10 有cr/lf 你真的很好 要发送的
回声:四季 你真的很好
回声:a
埃科:你真的很好 服务器: 服务器在9999上侦听
有cr/lf
四季 要发送的大小: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有一个双新行来结束其标题,并使用内容长度
或分块传输编码来通知另一方实体何时结束)
实际上,对于这样一个小例子,您可能看不到您的假设何时不起作用
但是,JSSE故意将发送的记录拆分为1/n-1。(OpenSSL将发送0/n)
因此,在这种情况下,问题更加明显
同样,这不是SSL/TLS或Java问题,解决这一问题的方法是将您读取的输入视为流,而不是假设您在一端读取的缓冲区大小将与用于从另一端发送数据的缓冲区大小相匹配。非常感谢。我以前的SSL经验是使用bytes和ETX的,这非常有限,效果非常好。