Lire les données envoyées par un serveur

Fermé
emmy_2019 Messages postés 59 Date d'inscription mardi 23 avril 2019 Statut Membre Dernière intervention 16 septembre 2019 - Modifié le 23 avril 2019 à 12:35
emmy_2019 Messages postés 59 Date d'inscription mardi 23 avril 2019 Statut Membre Dernière intervention 16 septembre 2019 - 30 avril 2019 à 14:08
Bonjour,

J'ai un capteur qui va envoyer à notre Systeme un fichier XML ( le capteur envoie un requete POST http qui contienne le text xml vers une adresse ip et un port spécifics) . Du coup mon problème est que je ne sais pas comment je pourrais lire ces données envoyées par le POST . J'ai essayé avec un socket TCP ( une adresse ip et un port spécifics) mais le recv ne m'a rien retourné. Aves-vous une idée svp?

char buffer[1024] = "";
int nOctetsRecus = 0;
int nOctetsEnvoyes = 0;
int tailleBuffer = 0;
int boucle = 1;
char * URL;
char * xml_data;
nOctetsRecus = 0;
nOctetsEnvoyes = 0;
tailleBuffer = 0;
boucle = 1;

//STEP1: Initialisation Winsock
iwsaStartup = WSAStartup(MAKEWORD(2,2), &winSockData);
if (iwsaStartup != 0)
{
printf("APICP: open_socket(): WSAStratup Failed\r\n");
}
//LOG_INFO("APICP: opensocket(): WSAStarup Success\r\n");

//STEP3: Socket TCPSocketClient Creation
TCPSocketClient = socket(AF_INET, SOCK_STREAM, 0);
if (TCPSocketClient == INVALID_SOCKET)
{
printf("Socket creation failed with error: %d\r\n", WSAGetLastError());
WSACleanup();
return 1;
}
//printf("La socket %d est ouverte en TCP/IP.\n", TCPSocketClient);
// on configure l'interface de connexion
IRMAServer.sin_addr.s_addr = inet_addr(Addr_TCP_OBU); // adresse IP du serveur IRMA
IRMAServer.sin_family = AF_INET;
IRMAServer.sin_port = htons(49668); // sin_port et sin_addr doivent être en Network Byte Order // htons() convertit
//un entier court depuis l'ordre des octets de l'hôte vers celuidu réseau (host to network short)
//printf("Connexion a %s sur le port %d\n", inet_ntoa(IRMAServer.sin_addr), htons(IRMAServer.sin_port));
if(connect(TCPSocketClient, (SOCKADDR*)&IRMAServer, iIRMAServerLen) != SOCKET_ERROR) // si le client réussit à se connecter au serveur
printf("Connexion a %s sur le port %d\n", inet_ntoa(IRMAServer.sin_addr), htons(IRMAServer.sin_port));
else
printf("Erreur de connexion.");

//printf("buffer ");
recv(TCPSocketClient, buffer, 2048,0);
printf("buffer =%s", buffer);
A voir également:

1 réponse

[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
23 avril 2019 à 17:58
Salut emmy_2019,

Si ton programme doit recevoir une requête http POST, ton programme doit faire fonctionner un serveur et non pas un client.

https://docs.microsoft.com/en-us/windows/win32/winsock/complete-server-code

Après, tu devras parser la requête http et renvoyer une réponse... ce n'est pas un travail trivial.

Tu peux commencer par lire ceci :

https://medium.com/from-the-scratch/http-server-what-do-you-need-to-know-to-build-a-simple-http-server-from-scratch-d1ef8945e4fa

(cela utilise les sockets Unix, mais abstraction faite de cela, l'article est bien expliqué)

En plus de gérer les requêtes http, tu devras décoder les données reçues et parser le JSON.

Dal
1
emmy_2019 Messages postés 59 Date d'inscription mardi 23 avril 2019 Statut Membre Dernière intervention 16 septembre 2019
Modifié le 24 avril 2019 à 11:29
Merci beaucoup Dal,
J'ai fait un server TCP mais il me reste un soucis "bind failed with error 10013"
En fait, le capteur va m'envoyer de manière periodique une requête POST ( suite à chaque évènement). Vous trouverez en pièce jointe un exemple de requête envoyée par le capteur .
Avez-vous une idée comment peux-je faire pour recevoir ces requêtes suite à chaque évènement?
Je vous remercie par avance de votre retour
0
emmy_2019 Messages postés 59 Date d'inscription mardi 23 avril 2019 Statut Membre Dernière intervention 16 septembre 2019
24 avril 2019 à 11:27
int IRIS_http_tcp_doorstate(void)
{
WSADATA wsaData;
int iResult;

int ListenSocket;
int ClientSocket;

struct sockaddr_in address;

char recvbuf[3000]= {0};
int recvbuflen = DEFAULT_BUFLEN;
int addrlen = sizeof(address);
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}


// Create a SOCKET for connecting to server
ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}

address.sin_family = AF_INET;

address.sin_addr.s_addr = inet_addr(Addr_TCP_OBU);

address.sin_port = htons( PORT );
memset(address.sin_zero, '\0', sizeof address.sin_zero);
// Setup the TCP listening socket
iResult = bind( ListenSocket, (struct sockaddr *) &address, sizeof(address));
printf("bind : %d\n", iResult);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}


iResult = listen(ListenSocket, 10);
printf("listen : %d\n", iResult);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

// Accept a client socket
while(1)

{
ClientSocket = accept(ListenSocket, (struct sockaddr *)&address, (socklen_t*)&addrlen);
printf("accept %d\n", ClientSocket);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

// No longer need server socket
closesocket(ListenSocket);

// Receive until the peer shuts down the connection
do {

iResult = recv(ClientSocket, recvbuf, 3000, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);

printf("%s\n",recvbuf);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}

} while (iResult > 0);
}
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}

// cleanup
closesocket(ClientSocket);
WSACleanup();

return 0;
}
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
24 avril 2019 à 11:52
Les ports de 1 à 1023 sont des ports privilégiés.

Utilise un port supérieur à 1023, par exemple 8080, pour y mettre ton serveur.
0
emmy_2019 Messages postés 59 Date d'inscription mardi 23 avril 2019 Statut Membre Dernière intervention 16 septembre 2019 > [Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024
24 avril 2019 à 11:57
J'ai utilisé le port 49668
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 24 avril 2019 à 14:07
Je suis sous Linux et je ne peux pas tester ton code.

L'erreur survient après l'exécution de cette ligne :

iResult = bind( ListenSocket, (struct sockaddr *) &address, sizeof(address));

Je pense que le programme n'aime pas le contenu de ta struct.

En principe la struct passée à bind est peuplée par un appel préalable à
getaddrinfo()
, auquel tu passes le port en 2ème paramètre et la struct à peupler en 4ème. Cette initialisation est absente de ton code

Le code d'exemple de Microsoft dont j'ai posté le lien précédemment contient cette initialisation. Ce code est, par ailleurs, expliqué et détaillé pas à pas dans les pages suivantes qui peuvent clarifier les choses pour toi :

https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-server-application
https://docs.microsoft.com/en-us/windows/win32/winsock/creating-a-socket-for-the-server
https://docs.microsoft.com/en-us/windows/win32/winsock/binding-a-socket
https://docs.microsoft.com/en-us/windows/win32/winsock/listening-on-a-socket
https://docs.microsoft.com/en-us/windows/win32/winsock/accepting-a-connection
https://docs.microsoft.com/en-us/windows/win32/winsock/receiving-and-sending-data-on-the-server
https://docs.microsoft.com/en-us/windows/win32/winsock/disconnecting-the-server

Vois le 2ème lien et le 3ème en particulier sur la création du contenu de la
struct sockaddr
avec
getaddrinfo()
et comment c'est utilisé dans l'appel à
bind()
.
0