我想在Java中实现SSL代理。我基本上打开了两个插座browser-proxy
,proxy-server
,并运行两个线程,它们将写入proxy-server
他们从browser-proxy
读取的内容,反之亦然。每个线程看起来像这样:正确关闭SSLSocket
while (true) {
nr = in.read(buffer);
if (nr == -1) System.out.println(sockin.toString()+" EOF "+nr);
if (nr == -1) break;
out.write(buffer, 0, nr);
}
sockin.shutdownInput();
sockout.shutdownOutput(); // now the second thread will receive -1 on read
每个线程将只关闭输入套接字,以便最终两个套接字都关闭。
但是,如果我想使用SSLSocket
,该怎么办?看来shutdownOutput/Input
方法不支持那里。这是我得到的例外。
Exception in thread "Thread-35" java.lang.UnsupportedOperationException: \
The method shutdownInput() is not supported in SSLSocket
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.shutdownInput(Unknown Source)
我想出是:
try {
while (true) {
nr = in.read(buffer);
if (nr == -1) System.out.println(sockin.toString()+" EOF "+nr);
if (nr == -1) break;
out.write(buffer, 0, nr);
}
// possible race condition if by some mysterious way both threads would get EOF
if (!sockin.isClosed()) sockin.close();
if (!sockout.isClosed()) sockout.close();
} catch (SocketException e) {/*ignore expected "socket closed" exception, */}
我必须赶上,而忽略每一个我的插座结束时间插座异常结束。
我的问题是:
- 如果
shutdownInput()
不支持,怎么来的,我从SSLSocket
得到一个-1
答案。 对我的痛苦有更好的解决方案吗?我不认为有什么理智的,因为其中一个线程可能已经在阻止
read
方法,当另一个线程标记他“我完成了”。我看到将他踢出阻塞线程的唯一方法是关闭套接字并引发“闭合套接字”异常。我猜你可能会使用一些邪恶的多线程消息传递和异步数据读取的组合,以便向另一个线程表明你的工作已完成,但这太可怕了,我担心IntelliJ的风格警察会跟着我只是想这件事。)
澄清:我知道shutdownInput
和shutdownOutput
没有意义的,因为你不能有一个半双工TLS连接,按规格。但是,鉴于此,如何在Java中结束TLS连接而不发生异常?
请不要告诉我shutdownIput
对TLS没有意义。我知道,这不是我要求的。我问我还能用什么,为了关闭SSLSocket
正确(因此标题,“正确关闭SSLSocket”
当你说shutdownInput/Output不被支持时,你是什么意思?该方法是否会抛出异常?如果是这样,什么例外? – Pace
是的,它确实会抛出一个异常'线程中的异常“Thread-4”java.lang.UnsupportedOperationException:SSLSocket'中不支持shutdownInput()方法。我认为有足够知识回答我的问题的人已经知道,他们不支持SSL。 –
您能澄清为什么“现在第二个线程将在sockout.shutdownOutput()'上读取-1”吗?在你的例子中,推测,'in = sockin.getInputStream()'。 – Bruno