Lire les données envoyées par un serveur
emmy_2019
Messages postés
63
Statut
Membre
-
emmy_2019 Messages postés 63 Statut Membre -
emmy_2019 Messages postés 63 Statut Membre -
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?
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);
1 réponse
-
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-
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 -
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;
} -
-
-
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 lastruct sockaddr
avecgetaddrinfo()
et comment c'est utilisé dans l'appel àbind()
.
-