2

SSL で使用されるチャネルからクリーンなデータを取得し、暗号化されたデータをそこに書き込むことができるヘルパー モジュールを実装しました。私には、「DataProvider はインターフェースであるべきだ」と ;)):

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 の抽象基本クラスを実装しました。その実装のテスト中に、私は 2 つの関数を作成しました。1 つは SocketChannel でメッセージを受信し、データの送信に使用される SSLSocket は接続を閉じます。もう 1 つは、SocketChannel でメッセージを送信し、それで終了を開始します。さて、問題は、これらの手順を実行しても、データの受信に使用される SSLSocket が閉じないことです。

  1. engine.closeOutbound()
  2. エンジン.ラップ()
  3. channel.write(data) (はい、wrap() で取得したすべてのデータを送信したと確信しています)
  4. 受信 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());

最後のアサートに違反しています。

最初は、これは toRead に関連付けられた「バックグラウンド」スレッドがないためだと考えていたので、着信を消費してclose_notifyから最終的にソケットを閉じるために読み取り/書き込みを行う必要がありますが、それでもそうではありませんヘルプ。

何か案が?

4

2 に答える 2

3

非常に遅い回答ですが、既に送信している場合は close_notify を待つ必要はありません。RFC 2246 を参照してください。ただし、取得する必要があります。close_notify でどの程度正確に選択しているかはわかりません。

NB あなたのコードは意味がありません。ソケットは、閉じた場合にのみ閉じられますisClosed()接続ではなく、ソケットを指します。

于 2011-07-17T02:21:29.617 に答える