IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Comment remplacer STDIN_FILENO sous windows ?


Sujet :

Réseau C

  1. #1
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut Comment remplacer STDIN_FILENO sous windows ?
    Bonjour à tous,

    Ma question est dans le titre, comment puis-je remplacer STDIN_FILENO sous windows ?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Pour ça, le plus simple est de le définir toi-même:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #ifdef _WIN32
    #ifndef STDIN_FILENO
    #define STDIN_FILENO 0
    #define STDOUT_FILENO 1
    #define STDERR_FILENO 2
    #endif
    #endif

  3. #3
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Ok je vais tenter ça, mon but est en fait de rendre mes sockets non bloquants, j'ai vu qu'il y avait aussi la fonction WSAAsyncselect si j'ai bonne mémoire, il ne me reste plus qu'à trouver une doc !

    merci.

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    Bonjour à tous,

    Ma question est dans le titre, comment puis-je remplacer STDIN_FILENO sous windows ?
    Si c'est pour utiliser avec select(), laisse tomber. Ca ne fonctionnera pas. De toutes façons, il n'y a pas de descripteurs de fichiers sous Windows. C'est soit des 'handles' (SOCKET, par exemple), soit des adresses de type FILE * pour les flux.

    "Tout est ficher" est un concept Unix, non repris par Windows.

    Citation Envoyé par jbarreau-mainson Voir le message
    Ok je vais tenter ça, mon but est en fait de rendre mes sockets non bloquants, j'ai vu qu'il y avait aussi la fonction WSAAsyncselect si j'ai bonne mémoire, il ne me reste plus qu'à trouver une doc !
    Le sockets asynchrones (non-bloquants), c'est compliqué à gérer. Qu'est-ce qui ne va pas avec le mode par défaut ? Si il le faut, utilise les threads. Quel est le problème exactement ?

  5. #5
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Qu'est-ce qui ne va pas avec le mode par défaut ?
    Je souhaite réaliser un serveur multi clients et je coince un peu ...

    Et je ne veux pas utiliser de threads.

    Je bloque un peu sur l'algo de mon problème du coup car il faut que mon serveur ecoute, tout en gerant les clients déjà connectés.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    Je souhaite réaliser un serveur multi clients et je coince un peu ...

    Et je ne veux pas utiliser de threads.
    Ah ? Pourquoi ?
    Je bloque un peu sur l'algo de mon problème du coup car il faut que mon serveur ecoute, tout en gerant les clients déjà connectés.
    Processus ou threads. Pas trop le choix. La solution avec select() risque d'être très complexe...

    Quoiqu'il en soit, il n'y a pas du tout besoin de passer en asynchrone...

  7. #7
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Ah ? Pourquoi ?
    On me l'impose, et puis si deux threads attaquent la pile en meme temps c'est la pagaille.

    Bref mon problème reste l'algorithme ...

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    On me l'impose, et puis si deux threads attaquent la pile en meme temps c'est la pagaille.
    Certes, mais c'est pour ça que chaque thread a sa pile...
    Bref mon problème reste l'algorithme ...
    Alors tu veux utiliser select(), c'est ça ?

    Alors il faut une boucle avec select() qui surveille la socket du serveur (déclenchement par accept()) et les sockets clients crées par accept() au fur et à mesure de leur création. Ensuite, à chaque évènement (reception d'un message, par exemple), select() se débloque. Ca va faire une usine à gaz, mais si c'est demandé...

    A chaque déconnexion (volontaire, ou send() ou recv() qui retourne 0 ou erreur), il faut fermer le socket client correspondant et le retirer de la liste des sockets surveillés.

    Nota : sous Windows, le paramètre 1 de select() est ignoré...

    Il y a peut être un exemple sur mon site...

    http://emmanuel-delahaye.developpez....tes-reseaux-c/

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Si c'est pour utiliser avec select(), laisse tomber. Ca ne fonctionnera pas. De toutes façons, il n'y a pas de descripteurs de fichiers sous Windows. C'est soit des 'handles' (SOCKET, par exemple), soit des adresses de type FILE * pour les flux.

    "Tout est ficher" est un concept Unix, non repris par Windows.
    C'est inexact:
    Sous Windows, vu du kernel, tout est "objet Kernel" (donc, vu des programmes utilisateurs, "tout est handle".
    De plus, la CRT Microsoft implémente le concept de descripteurs de fichiers, en tant que surcouche par-dessus les handles (et les FILE* sont bien une surcouche par-dessus les descripteurs). Seulement, select() est faite pour marcher avec les sockets et ne supporte pas les descripteurs.

    Mais même en faisant un WaitForMultipleObjects() sur le socket (ou plus précisément un WSAEVENT) et l'entrée standard, on se retrouve avec un problème dû à la façon stupide dont l'entrée standard est gérée.

  10. #10
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Certes, mais c'est pour ça que chaque thread a sa pile...
    Ca c'est une usine à gaz !

    Je vais essayé de coder ton algo mem si ca reste un peu flou ...
    La fonction select() est dur à appréhender !

    L'algo donnera un truc de ce genre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for(;;)
    {
      Server Listen;
      si accept -> creation client
     
      select() ?
    }

  11. #11
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Alors il faut une boucle avec select() qui surveille la socket du serveur (déclenchement par accept()) et les sockets clients crées par accept() au fur et à mesure de leur création. Ensuite, à chaque évènement (reception d'un message, par exemple), select() se débloque. Ca va faire une usine à gaz, mais si c'est demandé...
    ça sera toujours moins qu'avec des threads (changement de contexte, création du thread).

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    La plupart des serveurs peuvent se contenter d'une boucle basée sur select(), même sous Windows, s'ils n'ont pas besoin de réagir à la console.

    C'est à partir du moment où il faut écouter autre chose que des sockets que ça se complique.

    Citation Envoyé par jbarreau-mainson Voir le message
    L'algo donnera un truc de ce genre ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for(;;)
    {
      Server Listen;
      si accept -> creation client
     
      select() ?
    }
    Non, il donnera un truc de ce genre-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    SOCKET server = socket();
    listen(server);
    LISTEDECLIENTS clients;
    for(;;)
    {
    	fd_set readfds;
    	FD_SET(server);
    	for all clients
    		FD_SET(clients[i]);
    	select(..., readfds, ...);
    	if(FD_ISSET(server))
    		accept(...)
    	for all clients
    		if(FD_ISSET(clients[i])
    			recv(clients[i]);
    }

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    Ca c'est une usine à gaz !

    Je vais essayé de coder ton algo mem si ca reste un peu flou ...
    La fonction select() est dur à appréhender !

    L'algo donnera un truc de ce genre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for(;;)
    {
      Server Listen;
      si accept -> creation client
     
      select() ?
    }
    Non. C'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    ouvrir le socket serveur (socket(), bind(), listen())
    DO
       programmer la surveillance des sockets ouverts (FD_SET)
       select()
       reagir a l'évènement qui a déclenché select (FD_ISSET)
       SI reception serveur
          client := accept(serveur)
       FIN SI
     
       POUR CHAQUE client 
          SI reception 
             err := recv(client, commande)
             reponse := traitement (commande)
             err := send (client, reponse)
          FIN SI
       FIN POUR CHAQUE
    FOREVER

  14. #14
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    Ok je vais tenter ça, mon but est en fait de rendre mes sockets non bloquants, j'ai vu qu'il y avait aussi la fonction WSAAsyncselect si j'ai bonne mémoire, il ne me reste plus qu'à trouver une doc !

    merci.
    Il y a un tutoriel sur l'utilisation des sockets non bloquants ici. L'utilisation de WSAAsyncSelect permet d'avoir un programme bien structuré (sans boucle, sans multi-threading, etc.) mais pour l'utiliser, il faut avoir créé une fenêtre (pas forcément visible ...), donc elle ne peut être proprement utilisée dans une application console à moins d'avoir deux threads : le thread principal et un autre thread pour contenir la fenêtre.

  15. #15
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Merci a tous pour ces explications, je regarde ça apres manger

    Non, il donnera un truc de ce genre-ci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    SOCKET server = socket();
    listen(server);
    LISTEDECLIENTS clients;
    for(;;)
    {
    	fd_set readfds;
    	FD_SET(server);
    	for all clients
    		FD_SET(clients[i]);
    	select(..., readfds, ...);
    	if(FD_ISSET(server))
    		accept(...)
    	for all clients
    		if(FD_ISSET(clients[i])
    			recv(clients[i]);
    }
    Dans ce cas présent, tous les sockets clients ont été au préalable déclarés et initialisés pour un nombre de clients definit n'est ce pas ?

  16. #16
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    Dans ce cas présent, tous les sockets clients ont été au préalable déclarés
    tableau : oui
    liste chainée : non
    et initialisés pour un nombre de clients definit n'est ce pas ?
    initialisé, non. (enfin à INVALID_SOCKET, oui).

    Le nombre de clients peut être variable. Il suffit d'une structure de données souple (tableau dynamique, liste chainée ...)
    ceci dit, on ne va peut être pas non plus accepter 500.000 clients en meme temps. Pour une machine donnée, il semnble que 1000 à 10000 soit le maximum (ajuster listen() en conséquence... 100, par exemple. Bien lire la doc...)...

    Il ne faut pas oublier les temps de traitement et de réponses... Si c'est du html, en gros, on émet 100 à 1000 caractères pour un reçu...

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Franchement, c'est dans ce genre de moments qu'il serait plus simple de programmer en C++: Le C++ propose des conteneurs qui te permettraient facilement de gérer ta liste de clients...

    Quant à ta question envoyée en MP (comment retrouver un client à partir d'un socket), ici, je pense que la recherche naïve suffira: Parcourir la liste client par client jusqu'à en trouver un qui a le bon socket. C'est en temps linéaire, et tu auras rarement besoin de faire ça en boucle de toute façon.

  18. #18
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Je viens de terminer l'écriture de mon serveur.c
    Voilà ce que ca donne : je pense avoir respecter l'algorithme et ça devient plus clair. Cependant lorsque je compile l'erreur renvoyée est "erreur lors du select".

    voilà mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    t_serveur serveur;
     
    WSADATA wsaData;
    char Buff[BUFF_SIZE];
     
    int i, max, actuel;
     
    int Serveur(int sc, int pa)
    {
        switch(sc)
        {
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Constructeur. Service NEW pour Serveur.
    //Création du serveur.
            case SERVEUR_NEW :
                if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
                {
                    Fin("Initialisation DLL Wsa : Echec.\n");
                }
                //Création de la Socket serveur : Protocole IPv4, Flux de données binaires, Protocole TCP ( mode "connecté")
                if((serveur.Sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
                {
                    Fin("Echec lors de la création de la Socket serveur.\n");
                }
     
                //Remplissage de la structure concernant les informations de la Socket
                serveur.Sin.sin_family       = PF_INET;              //Protocole IPv4
                serveur.Sin.sin_addr.s_addr  = htonl(INADDR_ANY);    //Ecoute sur toutes les adresses IP
                serveur.Sin.sin_port         = htons(PORTSQL);       //Port du serveur
     
                //Liaison de la Socket serveur avec la structure Sockaddr
                //La structure contenant les informations est Sockaddr_in, nous faisons donc un cast
                if(bind(serveur.Sock, (SOCKADDR *)&serveur.Sin, sizeof(serveur.Sin)) == SOCKET_ERROR)
                {
                    Fin("Echec du bind.\n");
                }
     
                if(listen(serveur.Sock, 0) == SOCKET_ERROR)
                {
                    Fin("Echec de l'écoute sur la Socket.\n");
                }
     
                t_client clients[NBMAX];
     
                fd_set readfds; //Descripteur : lecture
     
                max = serveur.Sock;
                actuel = 0;
     
                break;
     
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Service RUN pour Serveur.
            case SERVEUR_RUN :
                for(;;)
                {
                    FD_ZERO (&readfds);
                    FD_SET(serveur.Sock, &readfds);
     
                    for(i = 0; i <= actuel ; i++)
                    {
                        FD_SET(clients[i].Sock, &readfds);
                    }
     
                    if(select(0, &readfds, NULL, NULL, 0) == -1)
                    {
                        Fin("Erreur lors du select().");
                    }
     
                    if(FD_ISSET(serveur.Sock, &readfds))
                    {
                        serveur.Csock = accept(serveur.Sock, (SOCKADDR *)&(serveur.Csin), &(serveur.Sinsize));
                        if(pa == INVALID_SOCKET)
                        {
                            Fin("Echec de la connection du clients.\n");
                        }
                        printf("\nNouvelle connexion : %s se connecte.\n", inet_ntoa(serveur.Csin.sin_addr));
                        strcpy(Buff, "-- Bienvenue sur le serveur SQL");
                        send(clients[i].Sock, Buff, (int)strlen(Buff), 0);
     
                        max = serveur.Csock > max ? serveur.Csock : max;
     
                        FD_SET(serveur.Csock, &readfds);
     
                        t_client c = { serveur.Csock };
                        strncpy(c.pName, Buff, BUFF_SIZE - 1);
                        clients[actuel] = c;
                        actuel++;
                    }
                    else
                    {
                        for(i = 0; i <= actuel ; i++)
                        {
                            if(FD_ISSET(clients[i].Sock, &readfds))
                            {
                                Serveur(SERVEUR_RECV, 0);
                                Serveur(SERVEUR_SEND, 0);
                            }
                        }
                    }
     
                }
                break;
    (...) 
    }
    return 0;
    }

  19. #19
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par jbarreau-mainson Voir le message
    Je viens de terminer l'écriture de mon serveur.c
    Voilà ce que ca donne : je pense avoir respecter l'algorithme et ça devient plus clair. Cependant lorsque je compile l'erreur renvoyée est "erreur lors du select".

    voilà mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    t_serveur serveur;
     
    WSADATA wsaData;
    char Buff[BUFF_SIZE];
     
    int i, max, actuel;
     
    int Serveur(int sc, int pa)
    {
        switch(sc)
        {
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Constructeur. Service NEW pour Serveur.
    //Création du serveur.
            case SERVEUR_NEW :
                if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
                {
                    Fin("Initialisation DLL Wsa : Echec.\n");
                }
                //Création de la Socket serveur : Protocole IPv4, Flux de données binaires, Protocole TCP ( mode "connecté")
                if((serveur.Sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
                {
                    Fin("Echec lors de la création de la Socket serveur.\n");
                }
     
                //Remplissage de la structure concernant les informations de la Socket
                serveur.Sin.sin_family       = PF_INET;              //Protocole IPv4
                serveur.Sin.sin_addr.s_addr  = htonl(INADDR_ANY);    //Ecoute sur toutes les adresses IP
                serveur.Sin.sin_port         = htons(PORTSQL);       //Port du serveur
     
                //Liaison de la Socket serveur avec la structure Sockaddr
                //La structure contenant les informations est Sockaddr_in, nous faisons donc un cast
                if(bind(serveur.Sock, (SOCKADDR *)&serveur.Sin, sizeof(serveur.Sin)) == SOCKET_ERROR)
                {
                    Fin("Echec du bind.\n");
                }
     
                if(listen(serveur.Sock, 0) == SOCKET_ERROR)
                {
                    Fin("Echec de l'écoute sur la Socket.\n");
                }
     
                t_client clients[NBMAX];
     
                fd_set readfds; //Descripteur : lecture
     
                max = serveur.Sock;
                actuel = 0;
     
                break;
     
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Service RUN pour Serveur.
            case SERVEUR_RUN :
                for(;;)
                {
                    FD_ZERO (&readfds);
                    FD_SET(serveur.Sock, &readfds);
     
                    for(i = 0; i <= actuel ; i++)
                    {
                        FD_SET(clients[i].Sock, &readfds);
                    }
     
                    if(select(0, &readfds, NULL, NULL, 0) == -1)
                    {
                        Fin("Erreur lors du select().");
                    }
     
                    if(FD_ISSET(serveur.Sock, &readfds))
                    {
                        serveur.Csock = accept(serveur.Sock, (SOCKADDR *)&(serveur.Csin), &(serveur.Sinsize));
                        if(pa == INVALID_SOCKET)
                        {
                            Fin("Echec de la connection du clients.\n");
                        }
                        printf("\nNouvelle connexion : %s se connecte.\n", inet_ntoa(serveur.Csin.sin_addr));
                        strcpy(Buff, "-- Bienvenue sur le serveur SQL");
                        send(clients[i].Sock, Buff, (int)strlen(Buff), 0);
     
                        max = serveur.Csock > max ? serveur.Csock : max;
     
                        FD_SET(serveur.Csock, &readfds);
     
                        t_client c = { serveur.Csock };
                        strncpy(c.pName, Buff, BUFF_SIZE - 1);
                        clients[actuel] = c;
                        actuel++;
                    }
                    else
                    {
                        for(i = 0; i <= actuel ; i++)
                        {
                            if(FD_ISSET(clients[i].Sock, &readfds))
                            {
                                Serveur(SERVEUR_RECV, 0);
                                Serveur(SERVEUR_SEND, 0);
                            }
                        }
                    }
     
                }
                break;
    (...) 
    }
    return 0;
    }
    C'est volontaire la backlog à 0 dans listen()?

  20. #20
    Membre averti Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Points : 412
    Points
    412
    Par défaut
    Non, un oublie de ma part, modifié à NBMAX ( = 10 ).

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [PEAR] Comment installer Pear sous Windows ?
    Par horri dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 27/05/2012, 17h33
  2. Les logiciels sous Linux pour remplacer ceux sous Windows
    Par Nightfall dans le forum Contribuez
    Réponses: 23
    Dernier message: 15/02/2009, 22h21
  3. Réponses: 3
    Dernier message: 13/01/2007, 14h05
  4. Comment installer GMP sous Windows?
    Par Vinchol dans le forum Autres éditeurs
    Réponses: 9
    Dernier message: 13/07/2006, 10h05
  5. Réponses: 1
    Dernier message: 27/10/2005, 09h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo