2011-10-28 5 views
1

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

しかし、私は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(); 

    } 
} 

EDIT(。それは私が猛烈に最後の数時間のためにそれをいじりてきたので、現時点では少し厄介だごめんなさい):ここでは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

Ok ..実際には、私は何をすべきかがわかりません。 checkConnections関数は、recvを呼び出して入力を取得します。私はそれを読むために使うはずですか?または、私はrecvを後で呼び出せるように読むでしょう。 –

答えて

1

ここに問題があります。 main機能に1つ、newConnection機能で1:maxFDという名前の2つの変数があること

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

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

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

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

+0

ありがとうございました!!!これで完全に修正されました。あなたの卿(または奥さん)は私のヒーローです! –

+0

うん。私は愚かなような気がする。 –

関連する問題