Ich habe ein Hilfsmodul implementiert, das es mir ermöglicht, saubere Daten von einem mit SSL verwendeten Kanal zu erhalten und verschlüsselte Daten darin zu schreiben: Dies ist die relevante Schnittstelle (ich habe auch einige nicht abstrakte Methoden in dieser Klasse) , sagt so nicht zu mir, dass „Data Provider sollte eine Schnittstelle sein“;)):SSLEngine und schließen
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);
}
ich eine Implementierung dieser abstrakten Basisklasse für SSL haben. Während ich diese Implementierung getestet habe, habe ich zwei Funktionen geschrieben: In einem bekomme ich eine Nachricht mit einem SocketChannel und der zum Senden verwendete SSLSocket schließt die Verbindung, in dem anderen sende ich eine Nachricht mit dem SocketChannel den Abschluss damit ein. Nun ist das Problem, dass der SSLSocket verwendet, um die Daten zu empfangen, nicht schließt nicht, auch wenn ich diese Schritte erteilt habe:
- engine.closeOutbound()
- engine.wrap()
- channel.write (Daten) (ja, ich bin sicher, ich habe all Daten mit der Umhüllung()
- eine Auswahl des Kanals zum Lesen der eingehenden close_notify
das Problem ist, erhalten gesendet, dass die der Wahlschalter klemmt im 4. Schritt
In dem anderen Test (SSLSocket schließt die Verbindung) habe ich kein Problem.
Bitte beachte, dass ich die shouldClose wie implementiert haben:
return engine.isOutboundDone() && engine.isInboundDone();
so brauche ich einen eingehenden close_notify, um zu schließen, auch wenn ich die enge initialisiert haben (ich weiß nicht, ob dies richtig ist : schließlich kann ich es mit return engine.isOutboundDone()
)
Das ist mein SSLSocket Seite des Codes ist:
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());
die letzte assert verletzt wird.
Zunächst dachte ich, dass dies liegt daran, dass ToRead kein "Hintergrund" -Thread zugeordnet ist, also sollte ich einen Lese-/Schreibvorgang mit ihm durchführen, um den eingehenden close_notify
zu verbrauchen und dann endlich den Socket zu schließen, aber selbst das hilft nicht.
Irgendeine Idee?
Ich empfehle ernsthaft, dass Sie ein Framework wie Grizzly oder Apache MINA verwenden. Sie mischen verschiedene Programmierparadigmen. –
Was sind diese verschiedenen Programmierparadigmen, die ich zusammen mische? – akappa