4

私はCで書かれた非常に単純なTCPサーバーを持っています。それは無期限に実行され、接続を待機します。Windowsではselect、ソケットでのアクティビティをチェックするために使用します。アクティビティがない場合は、キーボードの「q」を押して終了できるようにする次のコードがあります。

if( kbhit() ) {
   char c = getch();
   if( c == 'q' ) break;
}

これはunixでは機能しません。これは、kbhit存在せず、getch動作が異なるためです。端末設定を変更し、文字ごとの入力を可能にするために使用するサンプルコードをいくつか見つけました。tcsetattrinit関数を呼び出した後、/ dev / stdin(with O_NONBLOCK)を開いて文字を読み取りますがread( f, &c, 1 )、文字がヒットするまでブロックします。

別のスレッドを生成して無期限待機させ、ユーザーが「q」を押した場合に最初のスレッドにシグナルを送ることができると思いますが、それは少し手間がかかるようです。確かにもっと簡単な方法はありますか?

4

3 に答える 3

5

選択ハンドルのリストに stdin を追加し、データがある場合は read を呼び出してそこから 1 文字を読み取ります。

于 2008-10-08T18:25:45.643 に答える
1

Unixでは、システムコンソールでもX端末ウィンドウでも、キーボードI/Oは仮想端末を経由します。デバイス/dev/ ttyは、最近では、プロセスの制御端末にアクセスするための通常の方法です。オープン/クローズ/読み取り/書き込み以外のデバイス操作はすべて、その特定のデバイスに対するioctl(2)システムコールによって処理されます。あなたがやりたいことの一般的な考え方は

制御端末を開きます(stdinである場合とそうでない場合があります)

その端末の動作モードを変更して、入力のフルラインを待たずに戻るようにします(これは通常のデフォルトです)

プログラムの残りの部分を続行します。その端末(stdinの場合もあります)からの読み取りは、エラーや終了条件になることなく、部分的な行またはゼロ文字を返す可能性があることを知っています。


2番目のステップの実行方法に関する詳細な回答は、Cプログラミングに関するよくある質問に記載されています。彼らはまた、これはOSの質問であり、言語の質問ではないと指摘しています。それらは9つの可能性を提供しますが、この質問に関連する3つの主要なものは次のとおりです。

  1. curses(3)ライブラリを使用する
  2. 古いBSDスタイルのシステムでは、sgttybを使用してCBREAKまたはRAWを設定します
  3. Posixまたは古いSystemVスタイルのシステムでは、TCGETAW / TCSETAWを使用してc_cc[VMIN]を1に設定し、c_cc[VTIME]を0に設定します。

C FAQのいくつかの参照に従うと、 kbhitコードフラグメントのこのページにつながる可能性があります。

于 2008-10-17T16:47:05.403 に答える
1

むしろ、あなたの

read( f, &c, 1 )

を押して通話を選択します。f が読み取り可能になると、文字が押され、read() はブロックされません。

于 2008-10-08T19:02:57.533 に答える