0

私は IMAP サーバーで作業しています。操作の 1 つは、(STARTTLSコマンドを使用して) TLS を使用するように接続をアップグレードすることです。現在のアーキテクチャには、ソケットからデータを読み取り、コマンドを解析し、チャネルを介して論理コマンドを送信するゴルーチンが 1 つあります。別のゴルーチンがそのチャネルから読み取り、コマンドを実行します。これは一般的にうまく機能します。

STARTTLSただし、 を実行するときは、現在進行中のRead()呼び出しを停止する必要があります。そうしないとRead()、TLS ハンドシェイクからのバイトが消費されます。間に別のクラスを挿入できますが、そのクラスはRead()呼び出しでブロックされ、同じ問題が発生します。ネットワーク接続がチャネルである場合、別の信号チャネルを追加し、select{}ブロックを使用して読み取りを停止できますが、ネットワーク接続はチャネルではありません (ゴルーチンとチャネルでラップするだけで、問題がそのゴルーチンに移動するだけです)。

Read()タイムアウトが期限切れになるなどを待たずに、通話が開始されたら通話を停止する方法はありますか?

4

2 に答える 2

0

Read()call は、内部でのオペレーティング システムの動作に依存します。そして、その動作はソケットの動作に依存しています。

ソケット インターフェース (オペレーティング システム間のほぼ標準ですが、多少の違いがあります) に精通している場合は、ソケットに同期通信モードを使用すると、readシステム コールがタイムアウト値が期限切れになるまで常にスレッドの実行をブロックすることがわかります。この動作を変更しないでください。

Go は、ゴルーチンが設計上不要な非同期通信を行うため、すべてのニーズに対して内部で同期 I/O を使用します。

壊れる方法もありreadます。ソケットを手動でシャットダウンすることです。これは、コードの最適な設計上の決定ではありません。また、特定のケースではそうではありません。したがって、タイムアウトを小さくするか、コードを再設計して、他の方法で動作するようにする必要があります。

于 2013-07-29T10:43:01.650 に答える
0

あなたまたは接続がない限り、通話を停止するためにできることはあまりありません。ReadSetReadDeadlineClose

bufioできることの 1 つは、パッケージでバッファリングすることです。これにより、実際にバッファから何かを読み取らずにPeekを実行できます。Peekと同じようにブロックReadしますが、何かが読み取れるようになったときに何をするかを決定できます。

于 2013-08-05T04:37:06.990 に答える