2012-03-18 4 views
0

私は2人のプレーヤーのゲームをプレイするcで単純なサーバーを作成しようとしています。着信接続を確認し、player1が存在しない場合、player1のファイルディスクリプタ(後で送受信に使用する)を保存し、player2がない場合も同様に動作します。私はHereから変更したこのループをセットアップしました。私の問題は、ある人から受け取って相手に送ることですが、私の割り当てが無効であるようです。 player2に送信しようとすると、失敗するか、またはゴミが送信されます。時には、player1に送信することがサーバーに返されます(?)。 selectを正しく使用して、ファイル記述子を正しくループしていますか?どんなフィードバックも高く評価されます。このソケット/ファイル記述子の割り当てが無効なのはなぜですか?

// add the listener to the master set 
FD_SET(listener, &master); 

// keep track of the biggest file descriptor 
fdmax = listener; // so far, it's this one 

// main loop 
while (1) { 
    read_fds = master; // copy it 
    if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { 
     error("select"); 
    } 

    // run through the existing connections looking for data to read 
    for(i = 0; i <= fdmax; i++) { 

     //This indicates that someone is trying to do something 
     if (FD_ISSET(i, &read_fds)) { 
      if (i == listener) { 

       addrlen = sizeof remoteaddr; 
       newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); 

       if (newfd == -1) { 
        error("accept"); 
       } else { 
        FD_SET(newfd, &master); 
        if (newfd > fdmax) { 
         fdmax = newfd; 
        } 

        /* If we have the maximum number of players, we tell if that it's busy */ 
        if (players >= 2) { 
         toobusy(fdmax); close(fdmax); FD_CLR(fdmax, &master); 
        } else {               
         //Problem here? 
         if (player1_fd == -1) { 
           player1_fd = newfd;         
         } 

         if ((player1_fd != -1) && (player2_fd == -1)) { 
           player2_fd = newfd;         
         } 

         players++; 
         if (players == 2) { 
           sendhandles(); //says two players exist 
         } 
        } 
       } 
      } else { 
       //Possible problems here 
       if (i == player1_fd || i == player2_fd) { 
        receive(i); //Processes the messages 
       } 
      } 
     } 
    } 
} 

答えて

0

toobusy部分は、fdmaxではなくnewfdを使用する必要があります。それ以外の場合は、このコードには簡単に見つからないエラーはありません。

あなたのコメント「時には、player1に送信するとサーバーに返信されます(?)」と表示され、player1_fdとplayer2_fdが初期化されていないか、-1の代わりに0に初期化されている可能性があります。ループの前に-1を設定したことを再度確認する必要があります。

数はさらにノート:

  • あなたはマスターが0に初期化されますか? FD_ZEROに電話しましたか?
  • masterをread_fdsにコピーするには、FD_COPYを使用する必要があります。

最後に、libeventやlibevなどのイベント処理にライブラリを使用することをお勧めします。

+0

うん、それは新しいです。ありがとう! – thomascirca

関連する問題