SimpleClientのメニューでWindowsはENTERキーなし(1文字入力検出)で動いています。
Linuxで、これを実現できないか?がテーマです。
実は、tty(teletypewriter)の属性を触ればできます。
ttyについて軽く触れておきましょう。
sshでログインしてttyというコマンドを実行してください。
標準入力、標準出力となっている端末デバイスを表示します。
実際に標準入出力がどうなっているか確認してみます。
現在のプロセスIDを調べてそのファイルディスクリプタを表示します。
標準入力0、標準出力1、標準エラー2がttyコマンドで表示されるデバイスに
なっていることがわかります。
標準入力がttyになっていることが確認できたのでttyの属性を変更して
kbhitと同様の関数をstdThread.cpp, stdThread.h追加しました。
ネットワークプログラミングの本質とは関係ないので解説はなしです。
残念ながらリモートデバッグの環境ではコンソール出力がttyではありませんので
これは使えません。これまで通りselectを使ったキー入力検査を使用します。
【SimpleClient.cpp】 #if 1 //////////////////////////////////////////////// // function // キーボード入力(改行まで)の取得 // 入力がないときはすぐにリターン // parameter // LPSTR pszString [in/out]データ格納用バッファ // int iSize [in]バッファのサイズ // return // 0:入力なし CMD_QUIT_CHAR:終了 CMD_SEND_MSG_CHAR:メッセージ送信 //////////////////////////////////////////////// int GetKeyString(LPSTR pszString, int iSize) { BOOL fRet = FALSE; int iRet = 0; if (kbhit()) { switch (getchar()) { case CMD_QUIT_CHAR: iRet = CMD_QUIT_CHAR; break; case CMD_SEND_MSG_CHAR: fprintf(stderr, “\nInput Msg : “); fgets(pszString, iSize, stdin); if (strlen(pszString) > 0) { // 改行まで読み込んでいるので if (pszString[strlen(pszString) – 1] == ‘\n’) pszString[strlen(pszString) – 1] = 0; iRet = CMD_SEND_MSG_CHAR; } break; default: break; } } return(iRet); } #else // リモートデバッグではttyじゃないのでkbhitは使えない int GetKeyString(LPSTR pszString, int iSize) { BOOL fRet = FALSE; int iRet = 0; fd_set rfds; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000 * 100; // 入力がなければ10mecのSleep FD_ZERO(&rfds); // fd_setの初期化 // 0:標準入力 1:標準出力 2:標準エラー FD_SET(0, &rfds); // 標準入力が調査対象 select(1, &rfds, NULL, NULL, &tv); if (FD_ISSET(0, &rfds)) // ENTERキー入力があった { memset(pszString, 0, iSize); read(0, pszString, iSize); switch (pszString[0]) { case CMD_QUIT_CHAR: iRet = CMD_QUIT_CHAR; break; case CMD_SEND_MSG_CHAR: fprintf(stderr, “\n送信メッセージを入力してください : “); memset(pszString, 0, iSize); read(0, pszString, iSize); // ENTERキーまで読み込む if (strlen(pszString) > 0) { // 改行まで読み込んでいるので if (pszString[strlen(pszString) – 1] == ‘\n’) pszString[strlen(pszString) – 1] = 0; iRet = CMD_SEND_MSG_CHAR; } break; default: break; } } return(iRet); } #endif