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

C Discussion :

TCP Problème Latence Client/Serveur


Sujet :

C

  1. #1
    Membre du Club Avatar de royal380
    Homme Profil pro
    Apprenti Ingénieur
    Inscrit en
    Mai 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprenti Ingénieur

    Informations forums :
    Inscription : Mai 2011
    Messages : 56
    Points : 54
    Points
    54
    Par défaut TCP Problème Latence Client/Serveur
    Bonjour,

    J'ai créé un jeu à 2 joueurs en réseau de "air hockey" (un client et un serveur qui déplace un palet pour renvoyer une balle) , mon problème est que par exemple lorsque je bouge le palet du joueur 1, le joueur 2 reçoit les nouvelles positions du palet1 mais avec un retard plus ou moins important.

    J'ai cherché du côté du TcpNoDelay , et de l'algorithme de Nagle mais je n'ai pas trouvé de commande en C qui me permettrai d'améliorer ça...

    J'ai déjà essayé çamais le compilo me dit ça :

    |4|warning: "REG_DWORD" redefined|




    Merci d'avance

    Royal

  2. #2
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    comment crée tu tes socket?
    comment gère tu l'écoute sur les sockets?

    bref est-il possible de voir une partie du code relatif a la création des socket ainsi que la lecture/écriture?
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Probablement REG_DWORD est déjà défini dans un des include <...> que tu utilises.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  4. #4
    Membre du Club Avatar de royal380
    Homme Profil pro
    Apprenti Ingénieur
    Inscrit en
    Mai 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprenti Ingénieur

    Informations forums :
    Inscription : Mai 2011
    Messages : 56
    Points : 54
    Points
    54
    Par défaut
    Mon fichier "*.h" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct paramClient
    {
        SOCKET socks;
        unsigned short PosC[2]; //Position du palet Client
        unsigned short PosS[2]; //Position du palet Serveur
        unsigned short PosB[2]; //Postion de la Balle (Commune)
     
    };
     
    typedef struct paramClient paramClient;
     
    void * envoie(void * p_data);
    void * recevoir(void * p_data);
    void client(paramClient *mesparams);
    mes 2 threads :

    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
    void * envoie(void * p_data) //thread envoie
    {
        struct paramClient * toto = (struct paramClient*) p_data; //création structure toto, + passage des paramètres "struct param mesparams"
     
     
        send(toto->socks,(char *)toto->PosC,sizeof(toto->PosC),0);
     
        return 0;
    }
     
    void * recevoir(void * p_data)  //thread de réception
    {
        struct paramClient * toto = (struct paramClient*) p_data; //création structure toto, + passage des paramètres "struct param mesparams"
     
     
        recv(toto->socks,(char *)toto->PosS,sizeof(toto->PosS),0);
     
        return 0;
    }
    mon client en localhost (je passe l'adresse de mon propre ordi):
    En localhost j'ai évidemment aucun décallage étant donné que je ne passe pas par le réseau.
    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
    void client(paramClient *mesparams)
    {
     
     
        WSADATA wsa; //On est sous win, donc fo initialiser les wsa(pas la peine de savoir ce que c'est)
        WSAStartup(MAKEWORD(2,0),&wsa); //on les initialise ici
        SOCKET sock; //Et voila notre socket !(ce n'est rien d'autre qu'une var int)
        SOCKADDR_IN sin;//Structure ds laquelle on va stocker les parametres du socket
        system("TITLE TCP Connection Maker (Version client)");
    //l'ip et le port quoi...
     
     
     
        char ip[15] = {"192.168.1.3"};
        int port; 
        port = 25000;
     
     
        sin.sin_family=AF_INET; //Ici, on dit qu'on veut un socket pour le net(me demandez pas a koi sa sert...)
     
        sin.sin_addr.s_addr=inet_addr(ip);//sin.sin_addr.s_addr est l'addresse de la variable contenue dans
    //la structure ou l'on stocke l'addr ip, inet_addr(char *ip) convertit la chaine ip en nombres
     
        sin.sin_port=htons(port);//sin.sin_port >> pareil ke pour l'ip
    //htons() convertit le port en un nombre utilisable par win
     
    //La structure sin est remplie, on peut commencer a utiliser le socket
        sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//On crée le socket ou du moins on l'initialise
    //AF_INET >> tjs pour le net, SOCK_STREAM >> pour utiliser le protocole TCP
     
        bind(sock,(SOCKADDR*)&sin,sizeof(sin));//On lie le socket à la structure sin pour définir ses parametres
    //(SOCKADDR*)&sin >> sert à convertir la structure SOCKADDR_IN en SOCKADDR
     
        if (connect(sock,(SOCKADDR*)&sin,sizeof(sin)))//essaie de se connecter, connect ressemble étrangement à bind
        {
            printf("La connection a echoue\n");//connect à renvoyé true, la connection à échoué
            system("PAUSE");//pour que l'user voie que sa a échoué avant que le programe ne ferme
            exit(0);//fin du prog
        }
     
        mesparams->socks=sock;
     
    }
    Et à chaque fois que je veux envoyer quelque chose je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    pthread_create(&thread_em,NULL,envoie,(void *)&posi);
    pthread_create(&thread_re,NULL,recevoir,(void *)&posi);
     /*posi = paramClient posi*/
    EDIT : /*J'ai essayé de mettre ça derrière ça améliore une peu la synchro*/
    pthread_join(thread_em, NULL);
    pthread_join(thread_re, NULL);


    Diogene :

    Je redéfinis REG_DWORD directement dans le fichier include alors ?

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 622
    Points
    23 622
    Par défaut
    Non. « REG_DWORD » est un symbole qui sert à indiquer un type de donnée. Plus précisément, ça sert à désigner une entrée de la base de registres Windows de format DWORD (32 bits).

    Si tu veux modifier le nagling, il faut modifier l'entrée de la base de registre correspondante. http://technet.microsoft.com/en-us/l...8WS.10%29.aspx

    Mais :

    1. Il n'y a aucune raison pour que cela affecte un programme comme le tien ;
    2. Le nagling est déjà actif par défaut, selon la page ci-dessus.


    Tu fais fausse route.

  6. #6
    Membre du Club Avatar de royal380
    Homme Profil pro
    Apprenti Ingénieur
    Inscrit en
    Mai 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprenti Ingénieur

    Informations forums :
    Inscription : Mai 2011
    Messages : 56
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Si tu veux modifier le nagling, il faut modifier l'entrée de la base de registre correspondante. http://technet.microsoft.com/en-us/l...8WS.10%29.aspx
    Justement j'avais trouvé l'info sur ce site et quand j'avais lu je pensais qu'il fallait changer la valeur de REG_DWORD pour enable/disable le nagling.

    EDIT : Euh je comprend pas l'explication pour changer la valeur du nagling , je suis allé dans regedit.exe mai après MYSTÈRE


    Citation Envoyé par Obsidian Voir le message
    1. Il n'y a aucune raison pour que cela affecte un programme comme le tien ;
    2. Le nagling est déjà actif par défaut, selon la page ci-dessus.


    Tu fais fausse route.
    Apparemment à l'inverse de ce que tu penses moi je voulais DISABLE le nagling car comme tu dis il est activer par défaut.
    Je pensais quand le désactivant les "petits" paquets seraient envoyés sans attendre. et donc meilleur synchro...

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 622
    Points
    23 622
    Par défaut
    Comment ça, « mystère » ? Tu sais comment fonctionne la base de registres, j'imagine… Ensuite, il faut avoir une vraie bonne raison d'aller modifier cette clé, car elle agit sur le système entier.

    En fait, ce n'est pas « TCPNoDelay » mais « TCP_NODELAY » que tu cherches. Le dernier est une option à passer au socket que tu utilises pour ta connexion, ce qui n'a rien à voir avec la clé de MSMQ.

    http://www.unixguide.net/network/socketfaq/2.16.shtml
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    Pour ce genre de choses, tu devrais typiquement utiliser UDP plutôt que TCP. C'est plus ou moins à cela que ça sert. Si ce n'est toujours pas suffisant, tu peux essayer de récupérer la MTU de ta liaison réseau et envoyer des paquets de cette taille. À ce stade, si le gain n'est toujours pas suffisant, il n'y aura plus grand chose à faire au niveau du réseau, sauf à vérifier s'il n'est pas anormalement lent.

    Ensuite, sache que si ton programme est déjà lent entre deux machines proches, il risque d'être inutilisable s'il doit être utilisé à travers Internet. Il faut absolument limiter autant que possible l'envoi de messages, quitte à donner à son homologue des informations sur la trajectoire prévue du palet et les laisser les calculer lui-même, en renvoyant un message de mise à jour si besoin.

  8. #8
    Membre du Club Avatar de royal380
    Homme Profil pro
    Apprenti Ingénieur
    Inscrit en
    Mai 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprenti Ingénieur

    Informations forums :
    Inscription : Mai 2011
    Messages : 56
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Comment ça, « mystère » ? Tu sais comment fonctionne la base de registres, j'imagine… Ensuite, il faut avoir une vraie bonne raison d'aller modifier cette clé, car elle agit sur le système entier.
    Au risque de te surprendre je n'y connait vraiment pas grand chose voir rien dans ce domaine.
    Je travail mon code au feeling en suivant des tutos à droite à gauche et d'ailleurs en parlant de ça je crois que je vais me lancer dans le C++ parce que dés que je fais une recherche google je tombe sur du C++ qui a l'air plutôt sympathique d'ailleurs.


    Citation Envoyé par Obsidian Voir le message
    En fait, ce n'est pas « TCPNoDelay » mais « TCP_NODELAY » que tu cherches. Le dernier est une option à passer au socket que tu utilises pour ta connexion, ce qui n'a rien à voir avec la clé de MSMQ.

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    J'essayerai ça +1

    Citation Envoyé par Obsidian Voir le message
    Ensuite, sache que si ton programme est déjà lent entre deux machines proches, il risque d'être inutilisable s'il doit être utilisé à travers Internet. Il faut absolument limiter autant que possible l'envoi de messages, quitte à donner à son homologue des informations sur la trajectoire prévue du palet et les laisser les calculer lui-même, en renvoyant un message de mise à jour si besoin.
    J'avais déjà lu des choses la dessus, c'est ce qu'on appel la prédiction ? Non ? Hélas j'ai un peu peur de ne pas trop être à la hauteur pour ce genre de chose mais bon pourquoi pas
    Et le jeu est uniquement destiné à un usage sur réseau LOCAL (LAN) entre pote


    EDIT:

    J'ai tenté de savoir ma MTU maxi avec:
    ping -f -l X octets 192.168.1.2 (< Adresse serveur sur le réseau), et j'ai donc trouvé une MTU de 1472+28 = 1500octets.
    Ce qui à l'air d'être tout à fait normal.

  9. #9
    Membre du Club Avatar de royal380
    Homme Profil pro
    Apprenti Ingénieur
    Inscrit en
    Mai 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Apprenti Ingénieur

    Informations forums :
    Inscription : Mai 2011
    Messages : 56
    Points : 54
    Points
    54
    Par défaut
    Bon j'ai trouvé une solution qui améliore pas mal la chose ...
    Je met un pthread_join(X,X) uniquement sur le thread de réception, je met un petit sleep(2 à 5ms) sur le client qui est en galère pour suivre le rythme du serveur ce qui réduit la vitesse de ma balle.

    Ensuite je multiplie la vitesse de déplacement par un plus grand facteur pour avoir l'impression que tout se passe bien sans lag.

    Merci pour votre aide.

    Sujet Résolu +1

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème UDP Client/Serveur : Reception impossible.
    Par qhardy dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 01/03/2009, 17h50
  2. problème configuration client/serveur
    Par aminlove88 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 28/01/2009, 09h32
  3. Problème talk client/serveur
    Par Irafelo dans le forum Réseau
    Réponses: 1
    Dernier message: 03/11/2008, 16h37
  4. Problème cube client/serveur
    Par zenati007 dans le forum Cognos
    Réponses: 1
    Dernier message: 15/04/2008, 18h13
  5. [ServerSocket]Problème communication client-serveur udp sur linux
    Par gdecrouez dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 29/09/2006, 14h59

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