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 :

Sockets Mcast/UDP paquets perdus


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mai 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2017
    Messages : 3
    Par défaut Sockets Mcast/UDP paquets perdus
    Bonjour,

    Je travail actuellement sur un projet de conversion de protocole UDP/MCast/Serie.
    Pour la partie serie RS232 je verrais plus tard.

    J'ai débuté mon projet avec une conversion Mcast->UDP Unicast. Sur mon ordinateur le résultat est conforme et tous les paquets reçus sont retransmis.
    Le problème se complique lorsque que j'ai voulu déployer le programme sur un autre ordinateur.

    Sur un autre ordinateur certain paquets sont perdus au delà d'environ 8000 caractères. sachant que les paquets arrivent par slave de 60 à 100 caractères. Apres plusieurs essais j'opterais pour un problème de gestion du buffer de la carte réseau qui ne se viderais pas assez vite à chaque lecture .
    Je m'explique: le serveur envoi en Mcast environ 200 lignes de 60 caractères toutes les 10 secondes (200*60=12000). Mon programme reçois environ 8000 caractères toutes les 10 secondes (8000 sur les autres PC. Sur mon PC ou tourne le compilateur c++ tout les caractères sont reçu).
    Autre point avec Wireshark TOUT les paquets sont reçu sur n'importe quel PC, il y a donc plus de paquets reçu sur un meme PC avec wireshark que le programme.

    J'ai fais quelques essais, mais sans resultat. Je fais appel au forum Developpez, dans lequel, quelqu'un aurai peut etre rencontré un probleme de ce type

    Le code:

    Code c++ : 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
    int main(int argc, char* argv[])
    {
            WSAData data;
            WSAStartup( MAKEWORD( 2, 2 ), &data );
     
            SOCKET sockfd, sockfd2;
            int reuse;
            int n,i;
            int recvlen;
            char buf[BUFSIZE];
            struct sockaddr_in recvaddr, sendaddr;
     
            struct ip_mreq {
            struct in_addr imr_multiaddr;   /* IP multicast address of group */
            struct in_addr imr_sourceaddr;  /* IP address of source          */
            struct in_addr imr_interface;   /* local IP address of interface */
            };
     
            struct ip_mreq group, group2;
     
            printf("Test Mcast - Unicast\n");
     
            //Socket de reception MCast
            if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
                    perror("Rx Socket fail\n");
    	        exit(1);
            }
     
            //	Socket d'émission UDP
    	if ((sockfd2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    		perror("Tx Socket fail\n");
    	        exit(1);
    	}
     
     
            //Init socket in
            reuse = 1;
    	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse));
            setsockopt(sockfd2, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse));
     
    	memset((char *)&recvaddr, 0, sizeof(recvaddr));
    	recvaddr.sin_family = AF_INET;
    	//recvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
            //recvaddr.sin_addr.s_addr = inet_addr("192.168.1.23");
            recvaddr.sin_addr.s_addr = inet_addr("172.16.1.1");
    	recvaddr.sin_port = htons(62000);
     
    	bind(sockfd,(struct sockaddr*)&recvaddr,sizeof(recvaddr));
     
    	//group.imr_multiaddr.s_addr = inet_addr("239.192.0.5");
            group.imr_multiaddr.s_addr = inet_addr("239.101.5.1");
            //group.imr_sourceaddr.s_addr = inet_addr("192.168.1.23");
            group.imr_interface.s_addr = htonl(INADDR_ANY);
    	setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof(group));
     
            //Init socket out
            memset((char *) &sendaddr, 0, sizeof(sendaddr));
            sendaddr.sin_family = AF_INET;
            sendaddr.sin_addr.s_addr = inet_addr("172.16.1.1");
            sendaddr.sin_port = htons(60005);
     
    	//bind(sockfd2,(struct sockaddr*)&sendaddr,sizeof(sendaddr));
     
     
            group.imr_multiaddr.s_addr = inet_addr("239.192.0.5");
            group.imr_interface.s_addr = htonl(INADDR_ANY);
    	setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof(group));
     
            while(1)
            {
                    //sprintf(buf,"Hello\n");
                    //sendto(sockfd2, buf, 6, 0, (struct sockaddr*) &sendaddr, sizeof(sendaddr));
                    //printf("Hello\n");
                    n = recvfrom(sockfd, buf, BUFSIZE, 0, (struct sockaddr *) &recvaddr, &recvlen);
                    if (n>=1)
                    {
     
                            if((sendto(sockfd2, buf, n, 0, (struct sockaddr*) &sendaddr, sizeof(sendaddr))) < 0)
                            {
                                    perror("Error Send2 : \n");
                                    exit(1);
                            }
     
     
                            buf[n] = 0;
                            //Affichage
    			for (i=0; i<n; i++)
    			{
    				if (buf[i] == 0)
    				buf[i] = 0x20;
    			}
                            printf("Recu: %s\n", buf);
     
                    }
            }
     
            return 0;
    }

    Merci

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    La perte de paquets est inhérente à UDP.
    Ensuite y'a le MTU qui limite aussi.
    Tous ces trucs sont quasi invisibles en réseau local, encore plus sur pc local, où tout semble bien se passer la très grande majorité du temps.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Comme l'évoque Bousk diminue déjà la taille des paquets. Un MTU de 1500 voire un peu moins n'est pas rare lorsque l'on emprunte le réseau public. Pour être sûr de passer limite-toi donc à (environ) 1400 octets par paquet.

  4. #4
    Candidat au Club
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mai 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2017
    Messages : 3
    Par défaut
    Bonjour,

    Merci pour vos réponses.

    Pour tester la taille des paquets j'ai remplacé la ligne 92:

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Recu: %s\n", buf);

    par

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Recu(%d): %s\n",n, buf);

    Les octets 'n' ne dépassent jamais 62

    Pour complement: le réseau est local. un PC A envoi des informations en multicast, un PC B les attends en unicast, donc un PC de conversion est sur le réseau pour convertir les données multicast en UDP. Comme expliqué: avec mon PC tout est convertie, des que j'utilise un autre PC les données sont droppés. Les PC A et B ne changent pas.
    Je sèche un peu...

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Pourrait-on voir un sendto plutôt pour avoir une vraie idée de la taille des paquets envoyés ?
    Encore une fois, la perte est inhérente à l'utilisation d'UDP. Si tu espères juste renvoyer des paquets sans perte, oublie.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Candidat au Club
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mai 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2017
    Messages : 3
    Par défaut
    Merci Bousk,

    Le plus étrange c'est que sur mon PC tout les paquets sont lu. Si je déploie le meme programme sur un autre PC la fin est perdu (quelque soit le uP).
    Sur toute les machines Wireshark vois la totalité des packets. Les packets ne sont pas perdu. Je pencherai plus pour un problème de codage.

    Nicxx13

Discussions similaires

  1. Programmation socket: client UDP
    Par ThE_BuG87 dans le forum C++
    Réponses: 3
    Dernier message: 08/01/2007, 12h25
  2. [SOCKET] Client UDP sur système Unix
    Par be_tnt dans le forum Développement
    Réponses: 1
    Dernier message: 14/04/2006, 21h31
  3. [Socket] Client UDP
    Par AxldenieD dans le forum Réseau
    Réponses: 12
    Dernier message: 22/11/2005, 12h59
  4. [Debutant] Problème Socket Linux UDP
    Par AxldenieD dans le forum Réseau
    Réponses: 3
    Dernier message: 01/11/2005, 17h08
  5. [UDP][Socket] perte de paquets et arret d'ecoute sur port
    Par Guismo1979 dans le forum Développement
    Réponses: 6
    Dernier message: 02/01/2003, 12h13

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