2011-10-28 45 views
1

我對Linux /套接字編程相當新穎。我正在使用select來檢查我的服務器程序中的連接(它最終將成爲聊天室服務器)。我正在使用telnet來測試它,併發生了一些奇怪的事情。當我第一次運行telnet(telnet localhost 5794)時,select返回1並將新連接添加到我的主文件描述符列表中。一切都很美好。使用Telnet測試select()

但是,然後我嘗試在telnet中輸入東西,沒有任何反應。選擇返回0,除非我打開一個新的telnet會話。

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,所以我可以在它進入函數時看到它。它從不打印。

+0

'select'返回後,你調用'accept',對吧?然後你在'accept'返回的套接字上調用'read'? –

+0

newConnect函數調用Accept並添加返回到主列表的文件描述符,但我沒有調用它讀取...我現在就試試這個。 –

+0

好吧......我不確定讀書應該做什麼。 checkConnections函數調用recv來獲得輸入。我應該使用閱讀嗎?或者稍後閱讀讓我打電話給recv。 –

回答

1

這是問題所在。

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

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

注意,有兩個變量命名maxFD:一個在main功能,一個在newConnection功能。改變一個不會改變另一個。建議:改爲使用全局。 (原因:整個應用程序只有一個需要訪問它的許多功能。)

這是一個非常非常基本的錯誤。如果你沒有敲打你的額頭,並說:「哦,這很明顯,」那麼你可能希望回頭看看編程書的介紹。

+0

非常感謝你!這完全解決了它。你先生(或女士)是我的英雄! –

+0

是的。我確實感到很傻。 –