Bonsoir,

J'implémente actuellement un protocole (RTCP) qui m'impose d'envoyer un packet UDP de ma machine A vers le serveur B. A la réception du packet, le serveur B va renvoyer un packet de réponse vers la machine A en UDP.

L'idée c'est que quand le réseau est bien pourrit, mon programme qui effectue un traitement est complètement bloqué car il est en attente de la réponse via recvfrom().

On m'a donc aiguillé sur select() et sur fcntl() mais ça ne marche pas comme prévu... En gros actuellement ça marche bien pour 2 envoi/réponses puis silence radio, plus aucun packet n'est reçu par le serveur. Je m'arrache les cheveux dessus, si quelqu'un pouvait m'aider...

Le but recherché étant juste d'envoyer des packets vers le serveur toutes les 5s et de récupérer les réponses une par une quand elles arrivent sans faire planter tout mon programme...

Les 2 premières ligne sont de l'objective-C m'enfin tout le reste est du C pur. La pour info la méthode sendRTCP() est appelée environ toutes les 0.5s dans un traitement "temps réel"

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
 
-(void)sendRTCP{
        NSDate* now = [NSDate date];
        // envoi toutes les 5s
        if ((_sentRTCPAudio == nil) || ([now timeIntervalSinceDate:_sentRTCPAudio] >= 5))
        {
                // si le file descriptor n'est pas initialisé, le faire
                if(!_fdRTCPAudio){
                        // socket
                        if( (_fdRTCPAudio = socket(AF_INET,SOCK_DGRAM,0)) < 0){
                                perror("rtcp aq fd failed");
                        }
                        // socket non bloquante ?
                        fcntl(_fdRTCPAudio, F_SETFL, O_NONBLOCK);
 
                        // select ?
                        FD_ZERO(&_readfs);
                        FD_SET(_fdRTCPAudio, &_readfs);
 
                        // initialisation de l'adresse de destination
                        bzero(&_audioServaddr,sizeof(_audioServaddr));
                        _audioServaddr.sin_family = AF_INET;
                        _audioServaddr.sin_addr.s_addr=inet_addr(_audioIP);
                        _audioServaddr.sin_port=htons(_rtcpAudio);
                        bind(_fdRTCPAudio, (struct sockaddr *)&_audioServaddr, sizeof(_audioServaddr));
                }
                uint8_t buf[7 * sizeof(uint32_t)];
                // ... on remplit le buffer
                int lenRTCP = 28;
 
                // on envoi le buffer
                if(sendto(_fdRTCPAudio,buf,lenRTCP,0,(struct sockaddr *)&_audioServaddr,sizeof(_audioServaddr)) < 0){
                        perror("rtcp aq failed here");
                        close(_fdRTCPAudio);
                        _fdRTCPAudio = nil;
                }
 
                // buffer de reponse
                unsigned char msg[50]; int n;
                bzero(msg, 50);
 
                // timeout sur le select
                struct timeval tv;
                tv.tv_sec = 0;
                tv.tv_usec = 200;
                int retval = select(_fdRTCPAudio + 1, &_readfs, NULL, NULL, &tv);
                if(retval == 0)
                {
                        printf("isset : )\n");
                        socklen_t len = sizeof(_servaddr);
                        if((n = recvfrom(_fdRTCPAudio,msg,sizeof(msg)-1,0,(struct sockaddr *)&_servaddr,&len)>0))
                        {
                                // reception de msg
                        }
                }
                printf("rtcpAQ sent\n");
        }
}