Telnetを使用してselect()をテストする

私はLinux /ソケットプログラミングにかなり新しいです。 select を使用してサーバープログラムの接続をチェックしています(最終的にチャットルームサーバーになります)。私はそれをテストするためにtelnetを使用していて、奇妙なことが起こっています。最初にtelnet(telnet localhost 5794)を実行すると、 select は1を返し、新しい接続をマスターファイル記述子リストに追加します。すべてがうまく見えます。

しかし、私はtelnetで物事を入力しようとしても何も起こりません。 Selectは新しいTelnetセッションを開くまで0を返します。

新しい接続を見つけるためだけに select ですか?私はそれも入力をチェックするために使用できると思った。以下は私のコードのコピーです(私は最後のカップルの時間のためにそれをひどく混乱させていたので、少し厄介です。

#include "chatpacket.cpp"
#include "serverFunctions.cpp"

#define SERVER_PORT 5794
#define MAX_PENDING 10

int main() {
  fd_set connections;
  fd_set waitingConnections;
  user *clients = new user[50];
  int serverSocket = ServerSetup (SERVER_PORT, MAX_PENDING);
  int maxFD = serverSocket;
  int ConnectionCount;

  struct timeval tv;

  FD_ZERO(&connections);
  FD_SET(0, &connections);
  FD_SET(serverSocket, &connections);

  tv.tv_sec = 1;
  tv.tv_usec = 100;

  bool shutdown = false;
  bool tmpflag = true;
  while(!shutdown) { 

    if (tmpflag == true){printf("in the loop!\n");tmpflag=false;}
    waitingConnections = connections;

    ConnectionCount = select((maxFD+1), &waitingConnections, NULL, NULL, &tv);

    if (ConnectionCount == -1) {
        ///HANDLE ERROR!!!!!!
        printf("Connection Error!");
    }
    else if (ConnectionCount > 0) {
      if (FD_ISSET(serverSocket, &waitingConnections)){
           newConnection(serverSocket, connections, maxFD, clients); //this works fine
      }
      else {
           checkConnections(clients, waitingConnections, maxFD); //the code never gets here
      }
    }

    //check keyboard
    shutdown = checkKeyboard();

  }
}

編集:ここでは、newConnectionのコードです:

bool newConnection(int serverSocket, fd_set& ConnectionList, int maxFD, user* userGroup){
    printf("in newConnection\n");
    struct sockaddr_storage remoteaddr;

    socklen_t addrlen = sizeof remoteaddr;

    int newFD = accept(serverSocket,(struct sockaddr *)&remoteaddr,&addrlen);
    FD_SET(newFD, &ConnectionList);

    if (newFD > maxFD)
        maxFD = newFD;

    printf("We have a new connection!!! (newConnetcion)\n");

    bool userAdded = false;
    for (int i = 0; i < 50; i++){
      if (userGroup[i].active == false){
            userGroup[i].socket = newFD;
            userGroup[i].active = true;
            userAdded = true;
                        printf("User added in the %ith position of the array.(socket number %i)\n",i,newFD);
            break;
      }
    }
    if (!userAdded)
        printf("new user was not added! (newConnetcion)\n");
}

checkConnections関数の先頭にはprintfがあり、関数に入るたびに確認できます。それは決して印刷されません。

1
select が戻ると、 accept を呼び出します。そして、 accept で返されたソケットで read を呼び出します。
追加された 著者 Dietrich Epp,
readrecv はソケットとほとんど同じです。 maxFD はインクリメントされますか?新しいソケットをfd_setに追加したことはありますか?
追加された 著者 Dietrich Epp,
最終的な「その他」の理由はありません。同時に着信データを受信することができます
追加された 著者 EJP,
newConnect関数はAcceptを呼び出し、マスターリストに返されたファイルディスクリプタを追加しますが、私はそれを読み込んだわけではありません...これを今試してみます。
追加された 著者 James - not really a pirate,
Ok。..​​実際には、私は読んだものが何をすべきかはわかりません。 checkConnections関数は、recvを呼び出して入力を取得します。私はそれを読むために使うはずですか?または、私はrecvを後で呼び出せるように読むでしょう。
追加された 著者 James - not really a pirate,
はいとはい。質問にcheckConnectionsのコードを追加しました。それはおそらく私が欠けている単純なものです。私は本当にあなたの助けに感謝します。
追加された 著者 James - not really a pirate,

1 答え

ここに問題があります。

int main(int argc, char *argv[])
{
    int maxFD = ...;
    ...
    newConnection(..., maxFD, ...);
    ...
}

void newConnection(..., int maxFD, ...)
{
    ...
    if (newFD > maxFD)
        maxFD = newFD;
    ...
}

maxFD という名前の変数が2つあります.1つは main 関数に、もう1つは newConnection 関数にあります。一方を変更しても他方は変更されません。推奨事項:代わりにグローバルを使用してください。 (理由:アプリケーション全体に1つだけあり、多くの機能がそれにアクセスする必要があります。)

これは非常に基本的なエラーです。もしあなたが額を叩かずに「ああ、それは明らかだ」と言えば、プログラミングの本の紹介に戻って見直したいかもしれない。

1
追加された
どうもありがとうございます!!!これで完全に修正されました。あなたの卿(または奥さん)は私のヒーローです!
追加された 著者 James - not really a pirate,
うん。私は愚かなような気がする。
追加された 著者 James - not really a pirate,