Problème de Socket

Problème de Socket - C - Programmation

Marsh Posté le 23-11-2007 à 20:35:21    

Bonjour à tous !  
Je suis nouveau ici alors me fachez pas si je ne sais pas trop utiliser le forum ;)
Alors voilà j'ai un problème de programmation de socket (en C).
Je ne m'occupe que du côté serveur, le client que l'on ma passé est déjà validé.
Les ports sont les MEMES des deux côtés.
port 5000 : RTP
port 5001 : RTCP
Je travaille sous XP, Visual Studio 2005, protocole UDP bien sûr.
IP serveur : 192.168.0.115
IP client :   192.168.0.104
 
1. Le serveur envoie des paquets RTP au client ---> OK
2. Je simule des pertes côtés serveurs ---> OK
3. Le client va donc détecter une perte et demande un renvoie de paquet RTP au serveur ---> OK
4. Un paquet RTCP spécial (appelé Nack) est renvoyé au serveur avec le numéro du paquet RTP perdu ---> OK
C'est avec le logiciel Wireshark que je vois que tout se passe bien.
 
Alors  voilà mon soucis.
Je dois donc développer un serveur qui ne s'occupe de ne recevoir que ces fameux Nack. Voici le code, très simple que j'ai fait.
J'ai enlevé quelques trucs pour que cela soit plus visible. Donc ne dites pas : il manque la déclaration de tel ou tel truc !
 
SOCKET SocketNack;
struct sockaddr_in client, serverNack;
clientAddressLength = sizeof(client);
SocketNack= socket(AF_INET, SOCK_DGRAM, 0);
 
serverNack.sin_family = PF_INET;
serverNack.sin_addr.s_addr = inet_addr("192.168.0.115" );
serverNack.sin_port = htons(5001);
 
if (bind(SocketNack,(struct sockaddr *) &serverNack,sizeof(serverNack)) < 0) {
cerr << "cannot bind socket";
exit(1);
}
 
while (1){
if (recvfrom(SocketNack, buffer, MAX_MSG, 0,(struct sockaddr *) &client,&clientAddressLength) < 0) {
cerr << " I/O Problem";
exit(1);
}
 
 
 
Donc le code reste bloqué sur le recvfrom pourtant d'après Wireshark j'ai bien les paquets Nacks qui vont de 192.168.0.104 vers 192.168.0.115, port 5001 vers 5001.
Donc comment ça se fait que je ne les reçoit pas ?
Alors j'ai regardé un peu le code du client (que je ne peux pas touché), il se figure que les Nack ne sont pas envoyés via la commande sendto mais send !
donc je suppose que si je fait send d'un côté il faut faire recv de l'autre ? send et recvfrom ne sont pas compatibles ?
alors s'il faut faire recv côté serveur, il doit falloir rajouter des commandes style accept() ? Mais ces commandes ne sont-elles pas réservées à TCP ? Moi je travaille en UDP (comme le montre le code).
Pouvez-vous m'aider ?
Merci d'avance !

Reply

Marsh Posté le 23-11-2007 à 20:35:21   

Reply

Marsh Posté le 23-11-2007 à 21:13:01    

ah oui au passage, côté client, avant le send, il n'y a pas de connect... c'est possible ça ??

Reply

Marsh Posté le 23-11-2007 à 23:45:49    

kus3000 a écrit :

ah oui au passage, côté client, avant le send, il n'y a pas de connect... c'est possible ça ??


Tu as bien dit UDP ? Pas de connect en UDP.

 

Il faut que la structure soit initialisée à 0 avant usage :

Code :
  1. struct sockaddr_in client = {0};
  2. struct sockaddr_in serverNack = {0};
  3. <...>


Message édité par Emmanuel Delahaye le 23-11-2007 à 23:54:01

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 25-11-2007 à 14:54:47    

merci pour la réponse, je vais voir lundi si cela marche mieux :)
mais pourquoi cette initialisation est nécessaire ?

Reply

Marsh Posté le 25-11-2007 à 19:39:02    

kus3000 a écrit :

merci pour la réponse, je vais voir lundi si cela marche mieux :)
mais pourquoi cette initialisation est nécessaire ?


Parce qu'il y a un tas de champs dans la structure et que c'est pas bon de laisser trainer n'importe quelle valeur n'importe où... Le comportement est indéterminé.
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-11-2007 à 09:44:52    

Bon j'ai rajouter les = {0}. Merci.
Mais j'ai toujours le problèmes, les Nacks (qui apparaissent sous Wireshark) ne sont pas récupérer sous Visual.
Le debbuger reste bloqué sur :  
recvfrom(ListeningSocketNack, buf_nack, MAXBUFLEN, 0,(struct sockaddr *)&ClientAddrNack, &ClientAddrLen)

Reply

Marsh Posté le 26-11-2007 à 19:32:08    

Je pense trouvé un élément de réponse...
en fait côté client la socket des nack n'est pas une socket udp mais une socket raw
alors ma question est : qu'est ce qu'une socket raw ?  
que doit-je faire côté serveur pour pouvoir recevoir des données issues d'une telle socket ? la fonction recvfrom est compatible avec une socket raw ?
Merci
 
PS : et pardon c'est bien un sendto et non un send dans le code du client, j'avais mal lu autant pour moi !

Reply

Marsh Posté le 26-11-2007 à 19:46:21    

kus3000 a écrit :

Je pense trouvé un élément de réponse...
en fait côté client la socket des nack n'est pas une socket udp mais une socket raw
alors ma question est : qu'est ce qu'une socket raw ?  


Une 'raw socket' ne gère pas de protocole de niveau 4 (TCP ou UDP, par exemple). C'est à l'applicatif de le faire (par exemple ping avec ICMP etc.).

Citation :


que doit-je faire côté serveur pour pouvoir recevoir des données issues d'une telle socket ? la fonction recvfrom est compatible avec une socket raw ?


Je sais pas.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-11-2007 à 09:30:41    

Ok merci pour cette réponse.
Le client est développé sous linux apparemment. La socket a été déclaré comme ci :
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
De mon côté sous windows, les termes PF_PACKET et ETH_P_ALL n'existe pas. Quels sont leur équivalent ?

Reply

Marsh Posté le 27-11-2007 à 09:42:11    

kus3000 a écrit :

Ok merci pour cette réponse.
Le client est développé sous linux apparemment. La socket a été déclaré comme ci :
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
De mon côté sous windows, les termes PF_PACKET et ETH_P_ALL n'existe pas. Quels sont leur équivalent ?

C'est plus compliqué que ça. J'ai trouvé un lien en chinois (mais le code est lisible)  qui montre du code portable :

 

http://topic.csdn.net/t/20050530/20/4046903.html

 

il doit exister ailleurs, Je te laisse jouer avec Google...
 

 


Message édité par Emmanuel Delahaye le 27-11-2007 à 09:54:15

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-11-2007 à 09:42:11   

Reply

Marsh Posté le 27-11-2007 à 13:30:45    

j'apprend de plus en plus au fur et à mesure que je tatonne... :)
est-ce que quelqu'un pourrait me dire comment faire pour que ma socket raw ne prenne que les données rentrantes (et pas les RTP qui sortent) car avec recvfrom j'ai tous les paquets que j'envoie et que je recois !
setsockopt(socket raw, .........) ?

Reply

Marsh Posté le 27-11-2007 à 13:51:50    

autre soucis : l'adress ip de l'ordinateur d'en face est 0.0.0.0

Reply

Marsh Posté le 27-11-2007 à 14:11:24    

en fait j'explique le projet :
j'ai mon pc sur lequel je code, qui est aussi le streamer
@ 192.168.0.115
il envoie des paquets rtp via le port 5000 (et reçoit les rtcp via le port 5001 donc)
 
j'envoie à un pc @ 192.168.0.104
 
entre les deux il y a un mini pc d'adresse 0.0.0.0, qui s'occupe lui de renvoyer les nack via le port 5001 (mêmes ports des deux cotés)
ce n'est donc pas le pc d'adresse 192.168.0.104 qui renvoie les nack mais ce pc d'adresse ip nulle.
 
le probleme est donc comment récupérer les nack envoyés par ce mini pc.
wireshark détecte parfaitement ces paquets (source : 0.0.0.0, destination : moi = 192.168.0.115)
mais visual studio, via les commande recv ou recvfrom passe par dessus !
 
pouvez-vous m'aider ?

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed