2011-10-28 3 views
1

Je suis relativement nouveau dans la programmation Linux/socket. J'utilise select pour vérifier les connexions dans mon programme serveur (il sera éventuellement un serveur de chatroom). J'utilise telnet pour le tester et quelque chose d'étrange se passe. Lorsque je lance telnet pour la première fois (telnet localhost 5794), select renvoie 1 et ajoute la nouvelle connexion à ma liste de descripteurs de fichier maître. Tout a l'air bien.Utilisation de Telnet pour tester select()

Mais ensuite j'essaye de taper des choses dans telnet et rien ne se passe. Select renvoie 0 sauf si j'ouvre une nouvelle session telnet.

Est-ce que select est juste pour trouver de nouvelles connexions? J'ai pensé que je pourrais l'employer pour vérifier la contribution aussi bien. Voici une copie de mon code (. Il est un peu en désordre au moment parce que je l'ai été déconner avec fureur pour les dernières deux heures, je suis désolé)

#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: Voici le code pour 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"); 
} 

la fonction checkConnections a un printf au début de celui-ci, je peux voir chaque fois qu'il entre dans la fonction. Il n'imprime jamais.

+0

Après le retour de 'select', vous appelez' accept', n'est-ce pas? Et puis vous appelez 'read' sur le socket retourné par' accept'? –

+0

La fonction newConnect appelle Accept et ajoute le descripteur de fichier retourné à la liste principale, mais je n'ai pas appelé read on ... Je vais essayer cela maintenant. –

+0

Ok..uniquement, je ne suis pas sûr de ce que la lecture est censée faire. La fonction checkConnections appelle recv pour obtenir une entrée. Suis-je censé utiliser lire pour ça? Ou va lire laissez-moi appeler RECV plus tard. –

Répondre

1

Voici le problème.

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

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

Notez qu'il existe deux variables nommées maxFD: un dans la fonction main et un dans la fonction newConnection. Changer un ne change pas l'autre. Recommandation: utiliser un global à la place. (Raison: Il n'y en a qu'un pour toute l'application et de nombreuses fonctions doivent y accéder.)

Il s'agit d'une erreur très, très basique. Si vous ne frappez pas votre front et dites: «D'oh, c'est évident», alors vous voudrez peut-être revenir en arrière et revoir une introduction au livre de programmation.

+0

Merci beaucoup !!! Cela l'a complètement corrigé. Vous monsieur (ou madame) êtes mon héros! –

+0

Oui. Je me sens un peu bête. –

Questions connexes