2012-03-18 129 views
0

我想寫一個簡單的服務器在C玩雙人遊戲。它檢查傳入的連接,如果沒有player1,它會保存player1的文件描述符(稍後用於發送和接收),如果沒有player2,它也會執行相同的操作。我有這個循環設置,我從Here修改。我的問題是我想從一個人那裏得到,併發送給另一個人,但似乎我的任務是無效的。當我嘗試發送給player2時,它失敗或發送垃圾。有時候,發送給player1會發送回服務器(?)。我是否正確使用選擇並循環正確設置文件描述符?對於任何反饋,我們都表示感謝。爲什麼此套接字/文件描述符分配無效?

// 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部分應該使用newfd而不是fdmax。否則,在這段代碼中不容易發現錯誤。

您的評論「有時候,發送給player1發送回服務器(?)」讓我認爲player1_fd和player2_fd可能未初始化,或者可能初始化爲0而不是-1。你應該仔細檢查你在循環之前將它們設置爲-1。

一些額外指出:

  • 確定主被初始化爲0?你有沒有給它打過FD_ZERO?
  • 您應該使用FD_COPY將主複製到read_fds。

最後,我建議使用庫來處理事件,比如libevent或libev。

+0

是的,這是newfd。謝謝! – thomascirca 2012-03-21 03:03:41