データを送信したいブロッキングSSLBIOオブジェクトがあります。問題は、接続がリモート側で閉じられており、読み取りを実行するまでそれを見つけることができないことです(BIO_writeはエラーを返しません)。ただし、ブロックしたくないので、送信する前に読むことができません。最後に、データの送信を担当するコードと読み取りを担当するコードは別々です。つまり、失敗した読み取りは別の送信をトリガーできません。これを修正するにはどうすればよいですか?
1 に答える
「閉」状態には 2 種類あり、「半閉」状態と呼ばれます。それらは主に、ソケットの一方または他方がアプリケーション データを送信するかどうかに関係しています。呼び出しが 0 を返す場合、recv
実際には、受信するデータがこれ以上ないことを通知しています。ただし、呼び出しがor などsend
の他の種類のエラーを通知しない限り、データを送信しても問題ありません (winsock でこれらに相当する Windows が何であるかはわかりませんが、それらがあることは知っています)。がエラーを返さない場合は、ソケットの反対側がまだデータを受け入れているためです。EPIPE
ECONNRESET
SSL_write
このrecv
呼び出しにより、「no more data」状態のノンブロッキング チェックが可能になり、次のように実行できます。
char c;
int r = recv(sock, &c, 1, MSG_DONTWAIT|MSG_PEEK);
r
がの場合0
、ソケットは相手側から保留中のデータがないという指示を受け取りました。それ以外の場合、呼び出しは1
1 バイトのデータ ( のために入力バッファにまだあるMSG_PEEK
)、または-1
. errno
がEAGAIN
( のために可能である) である場合、MSG_DONTWAIT
エラーはありません。他のerrno
値を参照する必要がありますが、ソケットが無効な状態にあり、閉じる必要があることを示している可能性があります。
ソケットが閉じられる前に、OpenSSL アプリケーションはSSL_shutdown
1 が返されたことを確認する必要があります。次に、オブジェクトが破棄されclose
た後にソケットで が発生します ( で)。これが意味することは、アプリケーションが何か異常を行わない限り、OpenSSL を使用するソケットの両側で戻りが確認され、両側で安全に接続を閉じることができるということです。SSL
SSL_free
SSL_shutdown
1
SSL
コンテキストのシャットダウン状態を確認したい場合は、 を使用できます。これは、相手側がシーケンスSSL_get_shutdown
を開始したかどうかを報告します。SSL_shutdown