Я реализовал вспомогательный модуль, который позволяет мне получать чистые данные из канала, используемого с SSL, и записывать в него зашифрованные данные: это соответствующий интерфейс (у меня также есть некоторые не абстрактные методы в этом классе , поэтому не говорит мне, что «DataProvider должен быть интерфейс»;)):SSLEngine и close
public abstract class DataProvider {
// Notify the bytes read from the net
public abstract void readFromNet(ByteBuffer b);
// Gets the bytes to write into the net
public abstract void writeToNet(ByteBuffer b);
// Add a message to send
public abstract boolean addMessage(byte[] data);
// Obtains the application data received
public abstract byte[] getReceivedApplicationData();
// True if there is something to actually send over the wire
public abstract boolean dataToSend();
// True if we should close the channel
public abstract boolean shouldClose();
// Notify our intention to shut down the connection
public abstract void shutDown(SelectionKey sk);
// Set the interest op set for the channel
public abstract void setInterestOps(SelectionKey sk);
}
Я реализацию этого абстрактного базового класса для SSL. При тестировании этой реализации я написал две функции: в одном я получаю сообщение с SocketChannel, а SSLSocket, используемый для отправки данных, закрывает соединение, а в другом я отправляю сообщение с SocketChannel, инициируя его закрытие. Теперь проблема в том, что SSLSocket используется для получения данных не закрывается, даже если я издал эти шаги:
- engine.closeOutbound()
- engine.wrap()
- channel.write (данные) (да, я уверен, что я послал все данные, полученные с обручем()
- отборный канала для чтения входящих close_notify
проблема заключается в том, что селектор застрял на 4-м шаге.
В другом тесте (SSLSocket закрывает соединение) У меня нет проблем.
Обратите внимание, что я реализовал shouldClose как:
return engine.isOutboundDone() && engine.isInboundDone();
так мне нужен входящий close_notify, чтобы закрыть, даже если я инициализирован близко (я не знаю, если это правильно : в конце концов, я могу изменить его с return engine.isOutboundDone()
)
Это моя SSLSocket сторона кода:
Socket toRead = socket.accept();
toRead.setSoTimeout(0);
InputStream is = toRead.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String read = "";
byte[] barray = new byte[1024];
while (read.length() < toSend.length() * 2) {
int bytesRead = is.read(barray);
bos.write(barray, 0, bytesRead);
read = new String(bos.toByteArray());
}
assertEquals(toSend + toSend, read);
assertTrue(toRead.isClosed());
Последние утверждают, нарушается.
Первоначально я подумал, что это связано с тем, что поток «background», связанный с toRead, отсутствует, поэтому я должен делать с ним чтение/запись, чтобы потреблять входящий close_notify
, а затем, наконец, закрыть сокет, но даже это не помогает.
Любая идея?
Я серьезно рекомендую использовать фреймворк, например, Grizzly или Apache MINA. Вы смешиваете разные парадигмы программирования. –
Что это за разные парадигмы программирования Я смешиваю вместе? – akappa