Problème de sockets asynchrones
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:
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");
}
} |