Envois de trame via socket udp

Fermé
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 - 28 août 2009 à 13:58
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 3 sept. 2009 à 14:59
Bonjour,
j'ai réaliser un programme en langage C, pour envoyer une trame d'un client a un serveur, le programme marche quand je met une donnée de type char, qd j'utilise la fonction recvto, mais dés que j''essais d'envoyer une structure sa plante sa ne marche pas, deja je reçois une erreur au niveau de la compilation:
error C2664: 'sendto' : cannot convert parameter 2 from 'struct buffer' to 'const char *'
je crois que j'ai mal définis mes paramétres ou je ne sais pas quoi, s'il vous plait aidez moi, j'ai plus beaucoup de temps devant moi et la j'arrive pas a m'en sortir
merci, j'attends vos répense
A voir également:

30 réponses

Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
28 août 2009 à 15:31
C'est normal, le prototype de sendto c'est :
ssize_t sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
C'est à dire que tu lui fourni un pointeur du nom de "buffer" qu'à partir de ca pointeur il va lire "length" octet et les envoyer au destinataire.
Si tu veux envoyer une structure c'est possible, mais il faut lui donner un pointeur et la taille de la structure.
Attention tout de même, il peux y avoir des problèmes d'alignement ou de taille de variable, si le client et le serveur sont compilés sur des machines d'architecture différentes.
Est-ce assez clair ?
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
28 août 2009 à 15:43
salut merci pour ta répense, bon c pas clair a 100% voici ma structure que je veux envoyer
struct buffer{
char nature[3];
char donnee[100];
};
j'ai lu dans un tuto que je devais declarer une variable de type buffer et lire ses composantes
buffer var;
printf(var.nature,"223");
printf(var.donnee,"appel frontal);
ensuite j'ai mis sa :
nombre_de_caractere=sendto(id_de_la_nouvelle_socket,var,sizeof(var),0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
sa a marcher normalement quand j'envoyer une chaine de caractére mais dés q j'utilise une structure sa ne marche pas, peut tu me corriger stp?
en faite je sumule sur le méme pc
merci, j'attends ta répense avec impatience
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
28 août 2009 à 16:00
nombre_de_caractere=sendto(id_de_la_nouvelle_socket,&var,sizeof(var),0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
ou
nombre_de_caractere=sendto(id_de_la_nouvelle_socket,&var,sizeof(struct buffer),0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
j'ai un doute que l'un soit le même que l'autre.
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
28 août 2009 à 16:03
j t'en remercie mais la 1ere j l'ai deja essayé mais sa n'a pas marcher, je ne sais pas si le probléme réside dans la structure ou je ne c pas. franchement je suis perdu la
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
28 août 2009 à 16:17
et la deuxième ?
le sizeof doit retourner 103.
Après peut être que ce con de windows teste les valeurs et que s'il voi 0 il stop l'envoi.
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
28 août 2009 à 16:22
méme répense avec le 2éme et c'est la méme que la 1ere fois:
error C2664: 'sendto' : cannot convert parameter 2 from 'struct buffer *' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
le probléme ne réside pas dans la structure? et la fçon dont j'ai spécifier les paramétres et declaré int?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
28 août 2009 à 16:24
le problème réside dans le fait que cette fonction est défini connement dans windows. Un simlple cast dynamiqe et le tour est joué (normalement) :
nombre_de_caractere=sendto(id_de_la_nouvelle_socket,(const char*)&var,sizeof(struct buffer),0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
pourtant, tu l'as bien fait ce cast pour les autres variable !?
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
28 août 2009 à 16:32
quand je fait se que tu viens de me dire je reçois sa, en plus de la méme erreur y'a un warning:
C:\Documents and Settings\abdel\Mes documents\test1\LTR\LTR.cpp(60) : warning C4518: 'char ' : storage-class or type specifier(s) unexpected here; ignored
C:\Documents and Settings\abdel\Mes documents\test1\LTR\LTR.cpp(60) : error C2664: 'sendto' : cannot convert parameter 2 from 'const int *' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.
sa me prend la téte se truc la franchement, sa a marcher normalement quand j'ai envoyer une chaine de caractére, je ne sais pk sa ne marche pas, ecoute pour la structure, et les declaration de var.nature et var.donnee c juste se que j'ai fais?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
31 août 2009 à 08:22
Oui, c'est juste. là c'est juste un problème à la con de conversion de type. Je ne sait pas pourquoi le compilateur fait chier ! il supporte bien le cast (struct sockaddr*)&information_sur_la_destination je ne voi pas pourquoi il fait chier pour var !
C'est peut être un truc spécifique à microsoft.
En fait, là tu as un pointeur sur une structure, mais en C, un pointeur c'est un pointeur : ça a la même taille les même attribut etc. c'est en fait une variable de type "long" qui stocke une adresse mémoire, la différence entre char* et int* par exemple c'est la manière dont les opérations seront faites dessus. Et normalement en C tu peux caster comme tu veux, c'est à dire que tu peux lui dire qu'en fait ta variable de type int* en fait elle pointe vers un objet de type struct bidule et inversement.
à la place de (const char*) tu peux essayé (void*)
ou alors la séquence suivante :
const char* c;
c=&var;// ou c=(const char*)(&var);
nombre_de_caractere=sendto(id_de_la_nouvelle_socket,c,sizeof(struct buffer),0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination)); 
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
31 août 2009 à 10:38
bonjour
sa a marcher du moin pour la compilation merci beaucoup, t'es vraiment trs gentil.
merci
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
31 août 2009 à 10:43
désolé si je te dérange mais a la réception je mets quoi dans recvto?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
31 août 2009 à 11:16
ba pareil.
L'idéal c'est de recevoir autant de bits que tu en envois. Comme tu es sur la même machine il n'y a pas de problème pour remplir la structure.
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
31 août 2009 à 11:19
oui je vois mais je met comme variable c? ou buffer ou quoi comme variable? ou var?, normalement j'ai envoyer l'adresse de var alors j fais sa?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
31 août 2009 à 11:47
???
Tu mets ce que tu veux et ce qui compile. Tu n'envoie pas l'adresse de var, tu passes à la fonction l'adresse de var, ce n'est pas pareil.
Je ne connais pas les détails de la fonction sendto, mais en gros ça doit resembler à ça :
for(int i=0;i<longueur_en_octet;++i)
{
      envoyer_par_udp(var[i]);// envoie d'un octet sur le réseau
}
Tu fournis à la fonction une adresse mémoire, et une longueur en octet, la fonction transmet simplement tous ces bits via le réseau. La mémoire d'un ordinateur est comme un énorme tableaux de bits groupés en octet. Un pointeur stock le numéro de la case à partir de laquelle est stocké une variable (il y a des variables de plusieurs octets, telle que int, long, structures etc.)
Donner un pointeur et une longueur reviens à donner une case de début et le nombre de case à lire dans le grand tableau qu'est la mémoire.
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
31 août 2009 à 15:28
re désolé j'ai pas bien pigé
bon j'ai creer ma structure qui est buffer qui contient 2 variable donnee et nature, je les ai definis avec var
aprés vous m'aviez dis de créer la vaiable c pour pointé l'adresse de var.
et la tu me demande de faire cette fonction, a quel niveau je la définis et quesque j'envois dans sendto dans le 2 eme parametre?
et dans la reception normalement dans la fonction recv, je dois recuperer le 2 eme parametre de sendto
merci et desolé pour le dérangement
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
31 août 2009 à 16:31
Non, non, je ne te dit pas de crer cette fonction.
Je l'ai mise pour essayer de t'expliquer comment fonctionne sendto.
Il faut que tu comprennes en premier lieu cette histoire de pointeur avant de compiler ton code. Il faut que tu comprennes pourquoi il faut mettre ça.
Si je te donne la solution, ça ne t'apportera rien, la preuve, tu ne comprends pas pourquoi je suis passé par "c".
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
1 sept. 2009 à 11:27
si si j'ai compris pk t m'a dit d passé par c pour stocké l'adresse de var et apré a la réception c s qu'on va recevoir, maintenant le truc qui me titille un peu c a la réception.
quand je met recvto je doit mettre le méme 2éme paramétre que celui qu'on a mis dans sendto, se qui implique que j doit mettr c qui qui pointe la variable var.
mais aprés avoir récupérer c je dois afficher la trame que j'ai reçu alors quesque je doit mettre pour le pritf? j'affiche *c? ou je met quoi, j'avoue que je ne maitrise pas trop sa, et qu'il faut que je finisse maxi demain ou aprés demain au plus tard alors sa commence a etre chaud, si t peux m'aider s sera super sympa
merci
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
2 sept. 2009 à 13:57
bonjour
vous etes la, j'ai vraiment besoin de votre aide s'il vous plait il faut que je finisse la, et je trouve plein de bug un peu partout j'ai beau cherché dans les forums, mais vu que j'ai pas trop le temps alors , j'ai besoin de votre aide
merci
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
3 sept. 2009 à 08:42
Et non, pas là hier.
Fait un effort pour la rédaction de tes messages, j'ai plus que du mal à les comprendre.
pour la réception, tu fait pareil, mais dans le sens inverse. C'est à dire que là il vaut mieux créer un pointeur sur structure. Donne ce que tu as écrit, je verrai pour corriger.
0
bellil.abdel Messages postés 34 Date d'inscription mercredi 8 avril 2009 Statut Membre Dernière intervention 3 septembre 2009 1
3 sept. 2009 à 10:19
bonjour
merci pour votre coopération
voici le programme client

#include "stdafx.h"
#include <winsock2.h> // pour les fonctions socket
#include <cstdio> // Pour les Sprintf
#include <stdio.h> /* pour entrees-sorties */
#include <stdlib.h> /* librairie */

#pragma comment(lib,"ws2_32.lib")
// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
SOCKET id_de_la_socket; // Identifiant de la socket
SOCKADDR_IN information_sur_la_destination; // Déclaration de la structure des informations lié au serveur
char var[33333]; // Tampon contenant les données reçues ou envoyées

SOCKADDR_IN information_sur_la_source; // Déclaration de la structure des informations lié à l'écoute
SOCKET id_de_la_nouvelle_socket; // Identifiant de la nouvelle socket
const char* c;
struct buffer
{
char nature[3];
char donnee[100];
};
typedef struct buffer buffer;

int main (int argc, char* argv[])
{
printf("\nBonjour, vous etes du cote LTR");

// ********************************************************
// Initialisation de Winsock
// ********************************************************
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
if (erreur!=0)
printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nWSAStartup : OK");

// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket=socket(AF_INET,SOCK_DGRAM,0);
if (id_de_la_socket==INVALID_SOCKET)
printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
else
printf("\nsocket : OK");

// ********************************************************
// Envoi des données
// ********************************************************
information_sur_la_destination.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
information_sur_la_destination.sin_addr.s_addr=inet_addr("172.16.192.68"); // Indiquez l'adresse IP du frontal
information_sur_la_destination.sin_port=htons(23); // Port 23 à destination du serveur


buffer var;
sprintf(var.nature,"223");
sprintf(var.donnee,"appel du frontal");

c=(const char*) (&var);
nombre_de_caractere=sendto(id_de_la_socket,c,1515,0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));

if (nombre_de_caractere==SOCKET_ERROR)
printf("\nDesole, je ne peux pas envoyer les donnees du a l'erreur : %d",WSAGetLastError());
else
printf("\nsend : OK");


// ********************************************************
// Fermeture de la socket correspondant à la commande socket()
// ********************************************************
erreur=closesocket(id_de_la_socket);
if (erreur!=0)
printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nclosesocket : OK");

// ********************************************************
// Quitte proprement le winsock ouvert avec la commande WSAStartup
// ********************************************************
erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
if (erreur!=0)
printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
printf("\nWSACleanup : OK");

return 0;
}
0