Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1725 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C/C++] Sockets en UDP, problème d'envoi à une IP

 



 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[C/C++] Sockets en UDP, problème d'envoi à une IP

n°379228
antsite
Je me souviens
Posté le 01-05-2003 à 09:35:23  profilanswer
 

Salut,
 
Je me heurte actuellement à un problème étrange, je n'arrive pas à envoyer avec sendto (udp):
 

Code :
  1. SOCKET s;
  2. SOCKADDR_IN localaddr, useraddr, tempaddr;
  3. int addrsize;
  4. s = socket(AF_INET, SOCK_DGRAM, 0);
  5. addrsize = sizeof(SOCKADDR_IN);
  6. localaddr.sin_family = AF_INET;
  7. localaddr.sin_addr.s_addr = INADDR_ANY;
  8. localaddr.sin_port = htons(5000);
  9. bind(s, (LPSOCKADDR)&localaddr, sizeof(localaddr));
  10. tempaddr.sin_family = AF_INET;
  11. tempaddr.sin_port = htons(5000);
  12. r = recvfrom(s, buf, sizeof(buf), 0, (LPSOCKADDR)&useraddr, &addrsize);
  13. ...
  14. //ce sendto marche (useraddr est "rempli" par le recvfrom precedent
  15. sendto(s, "test", 4, 0, (LPSOCKADDR)&useraddr, addrsize);
  16. //par contre quand je rempli moi même pour envoyer à une ip précise et bien le telnet sur cette ip ne reçoit rien...
  17. tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" );
  18. sendto(s, "test", 4, 0, (LPSOCKADDR)&tempaddr, addrsize);


 
par contre le telnet sur cette ip peut lui envoyer au serveur sans problème (

Code :
  1. s = socket(AF_INET, SOCK_DGRAM, 0);
  2. localaddr.sin_family = AF_INET;
  3. localaddr.sin_addr.s_addr = inet_addr("192.168.0.1" );
  4. localaddr.sin_port = htons(5000);
  5. bind(s, (LPSOCKADDR)&localaddr, sizeof(localaddr));
  6. size = sizeof(localaddr);
  7. sendto(s, in, strlen(in), 0, (LPSOCKADDR)&localaddr, size);


 
je ne comprends pas...
merci
   ANT


Message édité par antsite le 01-05-2003 à 21:37:30
mood
Publicité
Posté le 01-05-2003 à 09:35:23  profilanswer
 

n°379238
antsite
Je me souviens
Posté le 01-05-2003 à 10:28:20  profilanswer
 

Faut-il une socket par IP (toujours en UDP biensur) ? J'ai un doute...

n°379317
mrbebert
Posté le 01-05-2003 à 13:50:44  profilanswer
 

Je comprends pas pourquoi tu parles de telnet et d'UDP ?
C'est pas du TCP plutot ? [:figti]

n°379332
Konar
Posté le 01-05-2003 à 14:37:53  profilanswer
 

ANTSite a écrit :

Faut-il une socket par IP (toujours en UDP biensur) ? J'ai un doute...


 
une socket par ip+port. il te faut donc une 2eme socket et un 2eme bind.
 
par contre utiliser l'udp pour recevoir/envoyer sur une meme socket, moi j'eviterais, le tcp est un plus approprié.

n°379367
Deaddy
Posté le 01-05-2003 à 15:43:50  profilanswer
 

t'as juste besoin d'un socket par bind, et un bind par port que t'ecoute;
en emission, tu peux envoyer vers autant d'ip:port que tu veux avec le meme socket

n°379368
antsite
Je me souviens
Posté le 01-05-2003 à 15:46:28  profilanswer
 

Deaddy a écrit :

t'as juste besoin d'un socket par bind, et un bind par port que t'ecoute;
en emission, tu peux envoyer vers autant d'ip:port que tu veux avec le meme socket
 


 
Comment envoyer à plusieurs IP (cf mon code)
thx

n°379415
mrbebert
Posté le 01-05-2003 à 16:35:34  profilanswer
 

ANTSite a écrit :

Comment envoyer à plusieurs IP (cf mon code)
thx

En changeant les infos se trouvant dans le : (LPSOCKADDR)&useraddr :)  
 
Mais je vois pas comment tu comptes vérifier que le 2ème PC reçoit bien les infos. Pas avec telnet en tout cas :heink:

n°379423
antsite
Je me souviens
Posté le 01-05-2003 à 16:50:31  profilanswer
 

c'est exactement ce que je fais (cf code!) et le telnet c'est pas le telnet tcp windows mais un telnet perso, un client udp tout simple

n°379428
antsite
Je me souviens
Posté le 01-05-2003 à 16:56:34  profilanswer
 

Deaddy a écrit :

t'as juste besoin d'un socket par bind, et un bind par port que t'ecoute;
en emission, tu peux envoyer vers autant d'ip:port que tu veux avec le meme socket
 


 

Konar a écrit :


une socket par ip+port. il te faut donc une 2eme socket et un 2eme bind.


 
 
Qui a raison ?

n°379447
mrbebert
Posté le 01-05-2003 à 17:11:49  profilanswer
 

ANTSite a écrit :

c'est exactement ce que je fais (cf code!) et le telnet c'est pas le telnet tcp windows mais un telnet perso, un client udp tout simple

Là d'accord :)  
 
une socket UDP écoute sur un port. Elle ne peut donc recevoir des messages que sur ce port, mais pouvant provenir d'adresses sources différentes. De même, elle peut aussi émettre vers différentes adresses.

mood
Publicité
Posté le 01-05-2003 à 17:11:49  profilanswer
 

n°379541
Konar
Posté le 01-05-2003 à 18:08:56  profilanswer
 

ANTSite a écrit :


 
Qui a raison ?


 
aucune idée, t'as ka tester et tu nous diras...

n°379616
antsite
Je me souviens
Posté le 01-05-2003 à 19:16:48  profilanswer
 

Et bien c fait, c'est testé dans les 2 cas, je viens de créé une nouvelle socket exprès pour l'ip à laquelle je veux envoyer, je la crée comme dans mon code pour s, je la bind et paf le client à qui je veux envoyer reçoit toujours rien (testé avec 2 telnets (udp) un "pro" et un perso, pareil)...

n°379620
mrbebert
Posté le 01-05-2003 à 19:19:51  profilanswer
 

Peut être qu'il y a des champs mal initialisés. Reprends le useraddr qui marche, et réutilise le en changeant seulement l'IP de destination.

n°379623
antsite
Je me souviens
Posté le 01-05-2003 à 19:22:05  profilanswer
 

C'est exactement ce que j'ai fait avec un memcpy et après j'ai fait tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" ); ben pareil  :sweat:  
Le problème est peut être ailleurs, si vous voulez plus de code (tout le code ?), demandez...

n°379687
Konar
Posté le 01-05-2003 à 20:02:01  profilanswer
 

ANTSite a écrit :

C'est exactement ce que j'ai fait avec un memcpy et après j'ai fait tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" ); ben pareil  :sweat:  
Le problème est peut être ailleurs, si vous voulez plus de code (tout le code ?), demandez...


 
au lieu d'un sendto(), essaye ca (en testant bien les valeurs de retour des fct, et si erreur fais un WSAGetLastError)
 

Code :
  1. SOCKET s = socket(AF_INET, SOCK_DGRAM ,0);
  2. if (connect(s, (struct sockaddr*)&server, sizeof server) == SOCKET_ERROR)
  3. {
  4.  OutputDebugString("error connect" );
  5.  return 1;
  6. }
  7. send(s, "test", 4, 0);


n°379709
antsite
Je me souviens
Posté le 01-05-2003 à 20:27:30  profilanswer
 

Moi je veux bien mais je veux juste dire que je suis en UDP donc pas de connexion...
enfin bon j'ai fait un connect et y a pas d'erreur. Après le send je vois pas comment il pourrait marcher y a aucun destinataire d'indiqué nulle part... (contrairement à un sendto).

n°379721
Konar
Posté le 01-05-2003 à 20:35:16  profilanswer
 

ANTSite a écrit :

Moi je veux bien mais je veux juste dire que je suis en UDP donc pas de connexion...
enfin bon j'ai fait un connect et y a pas d'erreur. Après le send je vois pas comment il pourrait marcher y a aucun destinataire d'indiqué nulle part... (contrairement à un sendto).


 
arf... va falloir ke tu fasses plus de man que ca :
"
For a connectionless socket (for example, type SOCK_DGRAM), the operation performed by connect is merely to establish a default destination address that can be used on subsequent send/ WSASend and recv/ WSARecv calls.
"
 
le connect est justement la pour "indiquer le destinataire".
 
autre chose aussi : a moins d'une quelconque ratance au niveau du buffer dans le send, j'ai JAMAIS vu un send rater en udp.
(ca veut pas dire ke ca marche a tous les coups)
 
Pour ton truc d'envoyer des infos sur des ip differentes :
"
The default destination can be changed by simply calling connect again, even if the socket is already connected. Any datagrams queued for receipt are discarded if name is different from the previous connect.
"

n°379734
antsite
Je me souviens
Posté le 01-05-2003 à 20:40:35  profilanswer
 

Ouh la très intéressant, j'ignorais complètement tout ça...
Donc faut-il banir les sendto au profit des send  & connect ?
 
P.S. : Connectionless avec emploi de connect... la je comprends toujours pas pourquoi ça s'appelle mode non connecté  :)


Message édité par antsite le 01-05-2003 à 20:43:20
n°379739
Konar
Posté le 01-05-2003 à 20:47:02  profilanswer
 

ANTSite a écrit :

Ouh la très intéressant, j'ignorais complètement tout ça...
Donc faut-il banir les sendto au profit des send  & connect ?
 
P.S. : Connectionless avec emploi de connect... la je comprends toujours pas pourquoi ça s'appelle mode non connecté  :)  


 
Pur le sendto je sais pas trop, je m'en suis jamais servi, c'est juste que j'ai jamais eu de pb avec les fct de base (socket, connect, send).
 
sinon je te le re-dis, si tu veux envoyer/recevoir en te servant de la meme socket, va plutot falloir songer a faire du tcp.

n°379747
xWillow
Posté le 01-05-2003 à 20:52:58  profilanswer
 

sendto(s, "test", 4, 0, (LPSOCKADDR)&useraddr, addrsize);
 
je mettrai plutot
sendto(s, "test", 5, 0, (LPSOCKADDR)&useraddr, addrsize);
mais rien a voir avec la question, c'est juste que sinon il peux pas envoyer le '\0'

n°379749
xWillow
Posté le 01-05-2003 à 20:55:55  profilanswer
 

ok donc, le deuxieme sendto tu l'envois sur le port 5000 de ton soit disant telnet, mais par simple curiosité, verifie le port sur lequel tu envoie le premier sendto ( celui qui est rempli par le recv ) je ne pense pas que ce soit 5000 mais un port attribué aléatoirement. ( le port de reception n'etant pas le port d'envoie )


Message édité par xWillow le 01-05-2003 à 20:56:55
n°379750
antsite
Je me souviens
Posté le 01-05-2003 à 20:57:02  profilanswer
 

bon alors j'ai rajouté ça dans mon code
 
tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" );
SOCKET c = socket(AF_INET, SOCK_DGRAM, 0);
bind(c, (LPSOCKADDR)&tempaddr, addrsize);
connect(c, (LPSOCKADDR)&tempaddr, addrsize);
send(c, "test", 4, 0);
 
et bien le client n'a toujours rien
 
de plus j'ai aussi essayé ça (cf premier topic pour les variables,...)
tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" );
connect(s, (LPSOCKADDR)&tempaddr, addrsize);
send(s, "test", 4, 0);
 
et pareil (réemploi de la socket s et non une nouvelle comme c)

n°379751
xWillow
Posté le 01-05-2003 à 20:59:30  profilanswer
 

quelle est le code du serveur sur la deuxieme ip ?

n°379753
antsite
Je me souviens
Posté le 01-05-2003 à 21:01:41  profilanswer
 

xWillow a écrit :

ok donc, le deuxieme sendto tu l'envois sur le port 5000 de ton soit disant telnet, mais par simple curiosité, verifie le port sur lequel tu envoie le premier sendto ( celui qui est rempli par le recv ) je ne pense pas que ce soit 5000 mais un port attribué aléatoirement. ( le port de reception n'etant pas le port d'envoie )


 
cf premier post:
tempaddr.sin_family = AF_INET;  
tempaddr.sin_port = htons(5000);
 
edit: pardon j'avais pas compris ton post, mais alors comment faire pour envoyer à mon client si on ne connait pas le port ?
 
code du client "telnet":
la boucle de réception dans un thread

Code :
  1. while(!stop)
  2. {
  3.  strcpy(buf, "" );
  4.         r = recvfrom(s, buf, sizeof(buf), 0, 0, 0);
  5.  if(r == 0 || r == SOCKET_ERROR)
  6.   break;
  7.  buf[r] = '\0';
  8.         printf("- %s -\n", buf);
  9. }
  10. closesocket(s);


le main:
 

Code :
  1. s = socket(AF_INET, SOCK_DGRAM, 0);
  2. localaddr.sin_family = AF_INET;
  3. localaddr.sin_addr = inet_addr("192.168.0.1" );
  4. localaddr.sin_port = htons(5000);
  5. bind(s, (LPSOCKADDR)&localaddr, sizeof(localaddr));
  6. size = sizeof(localaddr);
  7. while(1)
  8. {
  9.         strcpy(in, "" );
  10.         gets(in);
  11.        
  12.         if(strcmp(in, "q" ) == 0) break;
  13.         else
  14.         {
  15.             printf("+ %s +\n", in);
  16.             sendto(s, in, sizeof(in), 0, (LPSOCKADDR)&localaddr, size);
  17.         }
  18. fflush(stdin);
  19. }


Message édité par antsite le 01-05-2003 à 21:23:07
n°379756
xWillow
Posté le 01-05-2003 à 21:03:43  profilanswer
 

ce que je veux dire, c'est est ce que l'ip 192.168.0.246 attend bien sur le port 5000 ?

n°379760
xWillow
Posté le 01-05-2003 à 21:06:35  profilanswer
 

je m'arrache un peu c'est rien
mais tu as pas besoin de faire de connect ni de faire plusieurs socket.

n°379761
Konar
Posté le 01-05-2003 à 21:07:40  profilanswer
 

ANTSite a écrit :

bon alors j'ai rajouté ça dans mon code
 
tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" );
SOCKET c = socket(AF_INET, SOCK_DGRAM, 0);
bind(c, (LPSOCKADDR)&tempaddr, addrsize);
connect(c, (LPSOCKADDR)&tempaddr, addrsize);
send(c, "test", 4, 0);
 
et bien le client n'a toujours rien
 
de plus j'ai aussi essayé ça (cf premier topic pour les variables,...)
tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" );
connect(s, (LPSOCKADDR)&tempaddr, addrsize);
send(s, "test", 4, 0);
 
et pareil (réemploi de la socket s et non une nouvelle comme c)


 
tu testerais bien toutes les valeurs de retour pour voir si y a pas d'erreur.
 
sinon, tu fais des closesocket() a des moments (serveur ou client) ? si oui faut refaire un appel a socket().
 
sinon la je vois pas trop, va ptet falloir que tu postes plus de code (si c pas trop gros)

n°379762
antsite
Je me souviens
Posté le 01-05-2003 à 21:08:18  profilanswer
 

j'ai édité.
Alors dis moi comment faire car j'y crois moi qu'il n'y a pas besoin de connect et de plusieurs sockets !!

n°379763
xWillow
Posté le 01-05-2003 à 21:08:40  profilanswer
 

je serai toi je reecrirai tout, je crois voir d'ou viens le probleme mais ca me fait chier de chercher =)

n°379769
mrbebert
Posté le 01-05-2003 à 21:13:01  profilanswer
 

Je crois pas non plus qu'il faille plusieurs sockets, ni de l'utilité du connect() ici [:figti]  
 
Essaie d'afficher le contenu de 'useraddr' et de 'tempaddr', pour essayer de voir où seraient les différences :/

n°379771
CtHuLhU50
Posté le 01-05-2003 à 21:16:08  profilanswer
 

                         Serveur udp
                             /\
                            /  \
                           /    \  
                          /      \
                         /        \
                        /          \
                       /            \
                      /              \
                 Client1(udp)     Client2(udp)
 
 
Voila le probleme il y a client1 ki envoye "test" au server comment fdaire pour ke le server envoi au client2 "test" ?
 
si on poivait avoir une source simple ;)
 
merci

n°379772
antsite
Je me souviens
Posté le 01-05-2003 à 21:17:12  profilanswer
 

Le code parce que je crois qu'il y a besoin:
tout ça est un thread
 

Code :
  1. SOCKADDR_IN localaddr, useraddr, tempaddr;
  2. s = socket(AF_INET, SOCK_DGRAM, 0);
  3. addrsize = sizeof(SOCKADDR_IN);
  4. localaddr.sin_family = AF_INET;
  5. localaddr.sin_addr.s_addr = INADDR_ANY;
  6. localaddr.sin_port = htons(5000);
  7. bind(s, (LPSOCKADDR)&localaddr, sizeof(localaddr));
  8. //Structure qui servira aux envois à toutes les IP//
  9. tempaddr.sin_family = AF_INET;
  10. tempaddr.sin_port = htons(5000);
  11. while(!r_stop)
  12. {
  13.         strcpy(buf, "" );
  14.         r = recvfrom(s, buf, sizeof(buf), 0, (LPSOCKADDR)&useraddr, &addrsize);
  15. if(r == 0 || r == SOCKET_ERROR)
  16.                break;
  17. buf[r] = '\0';
  18. if(strncmp(buf, "ttt", 3) == 0)
  19.              sendto(s, "ttt", 3, 0, (LPSOCKADDR)&useraddr, addrsize);
  20. else if(strncmp(buf, "yyy", 3) == 0)
  21. {
  22.              sendto(s, "yyy", 3, 0, (LPSOCKADDR)&useraddr, addrsize);
  23.                                                                
  24.              tempaddr.sin_addr.s_addr = inet_addr("192.168.0.246" );
  25.                  
  26.              sendto(s, "test", 4, 0, (LPSOCKADDR)&tempaddr, addrsize);
  27.         }
  28. }
  29. closesocket(s);


 
 
voila donc j'ai supprimé plein de trucs qui étaient superflus je pense et j'ai mis le code sans modif après les derniers posts (connect...)


Message édité par antsite le 01-05-2003 à 21:31:33
n°379773
xWillow
Posté le 01-05-2003 à 21:17:38  profilanswer
 

je suis en train d'essayer de recoder pour voir :)

n°379776
xWillow
Posté le 01-05-2003 à 21:19:38  profilanswer
 

dans tout tes sendto, quand tu mets la taille de l'envoie, tu mets juste le nombre de caractere, c'est pas correcte.
 il te manque la place pour envoyer le '\0', corrige stp =)

n°379778
xWillow
Posté le 01-05-2003 à 21:22:00  profilanswer
 

r = recvfrom(s, buf, sizeof(buf), 0, (LPSOCKADDR)&useraddr, &addrsize);
 
c'est pas sizeof(buf) mais strlen(buf) :)

n°379784
antsite
Je me souviens
Posté le 01-05-2003 à 21:24:10  profilanswer
 

xWillow a écrit :

r = recvfrom(s, buf, sizeof(buf), 0, (LPSOCKADDR)&useraddr, &addrsize);
 
c'est pas sizeof(buf) mais strlen(buf) :)


 
oui oui c'est noté.
Je pense pas que le problème soit là...  :)

n°379785
xWillow
Posté le 01-05-2003 à 21:24:44  profilanswer
 

oui, je dit ca juste a titre informatif :o

n°379789
xWillow
Posté le 01-05-2003 à 21:26:51  profilanswer
 

a mon avis, l'erreur viens du faite que tu binds avec un port des sockets qui ne le devraient pas, je suis en train de verifier

n°379796
CtHuLhU50
Posté le 01-05-2003 à 21:31:31  profilanswer
 

si jamais le server envoye une info  o client k il vient d envoyer kelke chose ca marche nikel
comme ceci :

Code :
  1. bind(c, (LPSOCKADDR)&to, sizeof(to));
  2. sizePeerAddr = sizeof(SOCKADDR_IN);
  3. r = recvfrom(c, buf, sizeof(buf), 0, (LPSOCKADDR)&to, &sizePeerAddr);
  4. if(r == 0 || r == SOCKET_ERROR)
  5. printf("pb envoye" );
  6. sendto(c, "test", 4, 0, (LPSOCKADDR)&to, sizePeerAddr);


 
ce qui marche pas si c le client envoye "test" au server é ke le server doit envoyer "test" a un autre client  

n°379798
mrbebert
Posté le 01-05-2003 à 21:33:34  profilanswer
 

Ca marche quand la srtucture 'to' est rempli par la fonction recvfrom(), mais pas quand celle ci est initialisée directement [:gratgrat]


Message édité par mrbebert le 01-05-2003 à 21:34:00
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C/C++] Sockets en UDP, problème d'envoi à une IP

 

Sujets relatifs
[PHP]Probleme d'execution de script avec Easy Phpprobleme avec une boucle
[ Python ] problème libftp [ resolu ][C] Probleme d'édition de lien
problème avec la mise à jour de données en VB avec ADO[ Python ] Problème avec Tkinter
Pitit probleme de selection (UP prob 2)Problème d'activeX = Comdlg32.ocx
problème avec tomcat[C]probleme de if for
Plus de sujets relatifs à : [C/C++] Sockets en UDP, problème d'envoi à une IP


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR