Aucune donnée reçue par la fonction recvfrom()

Fermé
Seji - Modifié le 16 déc. 2022 à 12:22
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 18 déc. 2022 à 17:48

Bonjour,

Dans le cadre d'un projet d'études, j'aimerais récupérer des données émise par un programme source en UDP avec une adresse, un port et une fréquence d'envoi réglable. Ainsi, j'ai repris un programme en C afin de récupérer les données via le port 50150. Celui-ci a fonctionné une seule fois mais depuis le programme reste bloqué dans la fonction rcvfrom().

J'ai regardé si la source envoyé des données via wireshark. Elle envoie bien des données par UDP sur le bon port : 50150. Je n'ai également pas d'erreur à la connexion au port correspondant. J'ai vérifié également par le biais du resource monitor que mon programme écoutait bien sur le bon port, ce qui est le cas aussi. Je n'arrive pas à savoir d'ou provient l'erreur pour l'acquisition des données.

Voici mon code:

#include <winsock2.h> // pour les fonctions socket
#include <cstdio> // Pour les Sprintf

#pragma comment(lib,"ws2_32.lib")

WSADATA initialisation_win32; 
int erreur;
int tempo; 
int nombre_de_caractere; 
char buffer[65535]; 
SOCKET id_de_la_socket; 
SOCKADDR_IN information_sur_la_source; 

int main (int argc, char* argv[]) {
    printf("\nEcoute du port 50150\n");

    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");

    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");

    information_sur_la_source.sin_family = AF_INET; 
    information_sur_la_source.sin_addr.s_addr = INADDR_ANY;
    information_sur_la_source.sin_port = htons(50150); // Ecoute sur le port 50150
    erreur = bind(id_de_la_socket, (struct sockaddr*) & information_sur_la_source, sizeof(information_sur_la_source));
    if (erreur != 0)
        printf("\nDesole, je ne peux pas ecouter ce port, code d'erreur : %d %d",erreur,WSAGetLastError());
    else
        printf("\nbind        : OK");

    tempo = sizeof(information_sur_la_source); 
    printf("\nbefore recvfrom");
    nombre_de_caractere = recvfrom(id_de_la_socket, buffer, 1024, 0, (struct sockaddr*) & information_sur_la_source, &tempo);
    printf("\nafter recvfrom");
    buffer[nombre_de_caractere] = 0; 
    printf("\nVoici les donnees : %s", buffer);

    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");

    erreur = WSACleanup(); 
    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;
}

Merci d'avance.
Windows / Firefox 107.0

3 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
15 déc. 2022 à 16:39

Bonjour,

Tu n'as pas reporter le code du client.

As-tu essayé de repartir de cette page ?

Bonne chance

0

Malheureusement je n'ai pas accès au code client, j'ai juste une interface sur laquelle je peux changer l'ip, le port et la fréquence d'envoi. De plus, le programme a fonctionné une seule fois sans changement particulier. Et je n'ai pas réussi à trouver les raisons de pourquoi il a fonctionné.

0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > Seji
16 déc. 2022 à 10:17

Rien ne t'empêche de tester avec ton propre client. Et concernant ton serveur, tu peux repartir du code donné dans le lien que j'ai donné. As-tu essayé ?

0
Seji > mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024
Modifié le 16 déc. 2022 à 10:41

Je vais essayer de reprendre un peu du code sur le lien que tu as envoyé, le réadapter à windows et tester tout ça.

0

J'ai donc essayé de faire un code client et re modifier mon code serveur mais mon code serveur ne reçoit pas le message du code client. Je n'arrive pas à voir d'ou vient mon erreur.

Voilà les 2 codes :

Serveur

// ********************************************************
// Les includes
// Cmd compilation : g++ receive.cpp -lws2_32 -o receive
// ********************************************************
#include <winsock2.h> // pour les fonctions socket
#include <cstdio> // Pour les Sprintf

// ********************************************************
// Les librairies
// ********************************************************
#pragma comment(lib,"ws2_32.lib")

// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32;
int erreur;
int tempo; 
int nombre_de_caractere;
char buffer[65535];
SOCKET sockfd;
SOCKADDR_IN serveraddr,cliaddr; 


int main (int argc, char* argv[])
	{
	printf("\nEcoute du port 8080\n");
	
	// ********************************************************
	// 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
	// DGRAM pour UDP, STREAM pour TCP
	// ********************************************************
	sockfd=socket(AF_INET,SOCK_DGRAM,0);
	if (sockfd==INVALID_SOCKET)
		printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
	else
		printf("\nsocket      : OK");

	// ********************************************************
	// Lie la socket à une ip et un port d'écoute
	// ********************************************************
	memset(&serveraddr,0,sizeof(serveraddr));
	memset(&cliaddr,0,sizeof(cliaddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_addr.s_addr=INADDR_ANY;  
	serveraddr.sin_port=htons(8080); 
	erreur=bind(sockfd,(const struct sockaddr*)&serveraddr,sizeof(serveraddr));
	if (erreur!=0)
		printf("\nDesole, je ne peux pas ecouter ce port, code d'erreur : %d %d",erreur,WSAGetLastError());
	else
		printf("\nbind        : OK");

	// ********************************************************
	// Reception des données
	// ********************************************************
	tempo=sizeof(cliaddr);
	printf("\nbefore recvfrom");
	nombre_de_caractere=recvfrom(sockfd,buffer,1024,0,(struct sockaddr*)&cliaddr,&tempo);
	printf("\nafter recvfrom");
	buffer[nombre_de_caractere]=0; 
	printf("\nVoici les donnees : %s",buffer);

	// ********************************************************
	// Fermeture de la socket correspondante à la commande socket()
	// ********************************************************
	erreur=closesocket(sockfd);
	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(); 
	if (erreur!=0)
		printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
	else
		printf("\nWSACleanup  : OK");
	}

Client :

// ********************************************************
// Les includes
// Cmd compilation : g++ send.cpp -lws2_32 -o send
// ********************************************************
#include <winsock2.h> // pour les fonctions socket
#include <cstdio> // Pour les Sprintf

// ********************************************************
// Les librairies
// ********************************************************
#pragma comment(lib,"ws2_32.lib")

// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32; 
int erreur; 
int tempo; 
int nombre_de_caractere; 
char buffer[65535]; 
SOCKET sockfd; 
SOCKADDR_IN serveraddr,cliaddr; 


int main (int argc, char* argv[])
	{
	printf("\nEcoute du port 8080\n");
	
	// ********************************************************
	// 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
	// DGRAM pour UDP, STREAM pour TCP
	// ********************************************************
	sockfd=socket(AF_INET,SOCK_DGRAM,0);
	if (sockfd==INVALID_SOCKET)
		printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
	else
		printf("\nsocket      : OK");

	// ********************************************************
	// Lie la socket à une ip et un port d'écoute
	// ********************************************************
	memset(&serveraddr,0,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET; 
	serveraddr.sin_addr.s_addr=INADDR_ANY; 
	serveraddr.sin_port=htons(8080); 
	// ********************************************************
	// Reception des données
	// ********************************************************
    char *hello=(char*)"Hello from client";
	sendto(sockfd,(const char *)hello, strlen(hello),0,(const struct sockaddr *)&serveraddr,sizeof(serveraddr));
    printf("Hello message sent.\n");
	
	// ********************************************************
	// Fermeture de la socket correspondante à la commande socket()
	// ********************************************************
	erreur=closesocket(sockfd);
	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(); 
	if (erreur!=0)
		printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
	else
		printf("\nWSACleanup  : OK");
	}
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 16 déc. 2022 à 12:22

Bonjour

Dans le code que je vois, on dirait que le main n'est pas écrit jusqu'au bout (pas de return 0, pas d'accolade fermante). C'est une erreur de copier coller ?

Pourquoi utilises-tu des variables globales, elles devraient être déclarées dans le main ?

Enfin, pourquoi n'utilises-tu pas le code reporté dans cette page, comme je te l'ai suggéré ? Certes, le code qui y est proposé est ce qu'on écrirait sous Linux, mais la seule différence entre windows et Linux c'est que sous Windows tu dois initialiser et fermer proprement winsocks (avec WSAStartup et WSACleanup) mais sinon tout le reste est identique.

Bonne chance

0

Oui il n'y avait pas de return mais les accolades sont bien fermantes. Je n'ai pas utilisé entièrement le code puisque je ne sais pas parmi les includes lesquelles gardés ou enlevés pour remplacer par le winsock2.h. Je n'arrive pas à utiliser les paramètres MSG_WAITALL et MSG_CONFIRM (' undeclared' ).

0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > Seji
16 déc. 2022 à 13:38

Utilise tes includes. Voici un autre exemple basé sur winsocks.

0
Seji > mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024
Modifié le 16 déc. 2022 à 14:49

Merci j'ai testé le code serveur du dernier exemple qui fonctionne avec mon programme client si je change l'ip de 192.168.0.000 à 127.0.0.1. Sauf que je ne sais pas qu'est ce qui fait que l'ip (localhost) fonctionne par rapport à l'autre ?

0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > Seji
18 déc. 2022 à 17:48

En IPv4, 127.0.0.1 signifie "soi-même", donc présuppose que le client et le serveur sont colocalisés sur la même machine. Si le code fonctionne ainsi, c'est qu'il est correct. Ensuite ton IP locale n'est vraisemblablement pas 192.168.0.000 mais probablement quelque chose comme 192.168.x.y où x est une valeur entre 0 et 254 et y une valeur entre 1 et 254. Tu peux vérifier quelle est ton IP en tapant la commande ipconfig /all dans les commandes MS-DOS. Attention à ne pas te tromper d'IP sinon ça ne pourra pas marcher.

0