1

糸脱毛をする必要があると思いますが、自分自身にいくつかの悪い習慣を教える前に、これが正しい方法で行われていることを確認したかったのです。

基本的に、受信者のIPアドレス:ポート(現在の場合は127.0.0.1:1300)をリッスンまたはpingするように指示できる「チャット」アプリケーションがあります。アプリケーションを2回開くと(最初はリッスンし、2番目はpingを送信します)、1つを選択してリッスンするように指示します(これは、pingメッセージを受信するまで常にリッスンするWhileステートメントです)。 pingを実行します。ピーチだけで動作します!

問題は、[pingをリッスン]ボタンをクリックすると、接着された「ダウン」モードになり、「視覚的に」フリーズしますが、UDPパケットメッセージがコンソールに出力されるため、実際にはフリーズしていないことがわかります。だから私の質問は、「リッスン」ボタンをクリックして「リッスン」すると同時に「作業中」のキャンセルボタンを使用して、時間がかかりすぎる場合にユーザーがプロセスをキャンセルできるようにする方法です。

4

1 に答える 1

2

これは、同期(ブロッキング)ソケットIOを使用しているために発生する可能性があります。サーバーアプリケーションはrecv()/read()でブロックする可能性が高く、データが到着するまでスレッドの実行をブロックします。次に、データを処理してブロック状態に戻ります。したがって、ボタンは押したままの状態でGTKによってレンダリングされます。

基本的に、この問題には2つの一般的なアプローチがあります。最初のものは糸脱毛です。しかし、私はより単純なアプリケーションではそれに対してお勧めします。このアプローチは一般にエラーが発生しやすく、適切に実装するにはかなり複雑です。

2番目のアプローチは非同期IOです。select()まず、 /関数を使用poll()して、複数のFDの1つが通知されるのを待つことができます(「データ受信」、「データ送信」、「接続受け入れ」などのイベントで)。しかし、メインループがすぐに利用できないGUIアプリケーション(GTKについてはよくわかりませんが、これは多くのGUIツールキットに当てはまります)では、これは通常不可能です。このような場合、汎用の非同期IOライブラリ(boost asioなど)を使用できます。GLIB、IIRCを使用すると、ソケットの相互作用のためのチャネルを作成し(g_io_channel_unix_new())、次にそれらにコールバックを割り当てることができます(g_io_add_watch())。これは、何か面白いことが起こったときに呼び出されます。

非同期IOの背後にある考え方は非常に単純です。つまり、OSに何かを実行するように要求し(データの送信、イベントの待機)、要求したことが完了するまで他の重要なこと(GUIの相互作用など)を実行します(そのようなイベントの通知を受け取るため)。

それで、あなたが次に勉強したいと思うかもしれないものはここにあります:

  • select()/ poll()(後者の方が一般的に使いやすいです)
  • asioライブラリをブースト
  • GLIBチャネルと非同期IO
于 2012-12-17T03:34:29.227 に答える