1

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

しかし、telnet で入力しようとしても何も起こりません。新しい telnet セッションを開かない限り、Select は 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 があるため、関数に入るたびに確認できます。決して印刷されません。

4

1 に答える 1

1

これが問題です。

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

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

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

これは非常に基本的なエラーです。額を叩いて「ああ、それは明らかだ」と言わない場合は、戻ってプログラミングの入門書を復習することをお勧めします。

于 2011-10-28T05:06:04.697 に答える