Go Down

Topic: ESP8266-12e serveur TCP (Read 358 times) previous topic - next topic

B_Remi

May 31, 2019, 10:14 am Last Edit: May 31, 2019, 12:25 pm by B_Remi
Bonjour,

Mon but est de faire un serveur TCP sur ma NodeMcu afin de pouvoir récupérer les valeurs d'un capteur de température et d'humidité.

Mon problème est que le port de destination n'est pas le même que le port de réception.

J'envoie mes données au port 5050 mais je reçois ces données sur un port totalement aléatoire donc je voudrais pouvoir le recevoir sur mon port 5050.

Je reçois aussi les trams sous une forme hexadécimale je ne sais pas si ceci est normal.

Code: [Select]
#include <ESP8266WiFi.h>
#include "DHT.h"

#define DHTPIN D4
WiFiServer server(5050);

DHT capteur(DHTPIN ,DHT22);

float h;
float t;

void setup() {
 
  Serial.begin(115200);
  WiFi.begin("XXXXXXXXXXX", "XXXXXXX"); 

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
  capteur.begin();
}

void loop()
{
  int bef;
  String Temp;
  String Hum;
  String trame;
 
  WiFiClient client = server.available();
 
  if (client) {
    if(client.connected())
    {
      Serial.println("Client Connected");
    }
   
    while(client.connected()){     
        bef = client.read();
        if(bef == 63){
            h = capteur.readHumidity();
            t = capteur.readTemperature();

             Serial.print("Humidite: ");
             Serial.print(h);
             Serial.print(" %\t");
             Serial.print("Temperature: ");
             Serial.print(t);
             Serial.print(" *C\n");

            Temp = String(t);
            Hum = String(h);
            trame = "<Temperature>" + Temp + "</Temperature><Humidite>" + Hum + "</Humidite>";

            //client.beginPacket(client.remoteIP(), client.remotePort());
            //Serial.print(port);
            client.write(trame.c_str(), trame.length());
        }
    }
    client.stop();
    Serial.println("\nClient disconnected");   
  }
}

lesept

1 : ne mets pas ton mot de passe en clair sur le forum...
2 : je ne suis pas sûr que ceci soit correct

Code: [Select]
 WiFiClient client = server.available();

Étudie bien l'exemple WiFiClient
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

B_Remi

Merci j'avais oublié pour le mot de passe.

Le lien que vous m'avez fourni et pour faire un client et moi je voudrait faire un serveur.

Un grand merci pour la vitesse auquel vous m'avez répondu.

hbachetti

Quote
J'envoie mes données au port 5050 mais je reçois ces données sur un port totalement aléatoire donc je voudrais pouvoir le recevoir sur mon port 5050.
Le port 5050 est celui qui est ouvert par le serveur pour l'attente des connexions.
A partir du moment où une connexion est acceptée, l'échange des données se fait sur une autre socket.
Je ne vois pas en quoi cela pose un problème, et de toutes façons tu n'y peux rien.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

lesept

Je viens de publier dans les projets terminés un message sur un simulateur de présence. Un des codes est un serveur sur ESP8266 (le code des prises), tu peux regarder si ça peut t'aider
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

B_Remi

En fait j'ai l'habitude de programmer sur un raspberry Pi en langage C/c++.

et le client ou le serveur que j'ai l'habitude de faire dessus répond sur le même port que celui d'écoute
donc j'aurais voulu que la note fasse de même

si ce n'est pas possible pas grave et merci quand même

hbachetti

Je suis surpris. En C l'acceptation d'une connexion (fonction accept() de la librairie) renvoie également le handle d'une nouvelle socket, donc cela revient au même.
C'est dans le principe même de TCP.

Quote
En fait j'ai l'habitude de programmer sur un raspberry Pi en langage C/c++ et le client ou le serveur que j'ai l'habitude de faire dessus répond sur le même port que celui d'écoute
Tu travailles peut-être d'habitude avec UDP ?
Auquel cas oui, le même port est utilisé, mais il n'y a pas de notion de connexion.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

B_Remi

j'ai bien fait en TCP

j'utilise Wireshark pour contrôler et le Src Port et le Dst Port sont les mamies

Merci lesept

hbachetti

Un source en C de ton serveur RASPBERRY PI aiderait à comprendre.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

hbachetti

#9
May 31, 2019, 04:55 pm Last Edit: May 31, 2019, 04:55 pm by hbachetti
Sus RASPBERRY utilises-tu recvfrom ou bien recv ?
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

B_Remi

#10
May 31, 2019, 06:59 pm Last Edit: May 31, 2019, 06:59 pm by B_Remi
classe client c++:

client.h:

Code: [Select]
#ifndef CLIENT_TCP_H
#define CLIENT_TCP_H

#include <string>
using namespace std;

class Client_tcp
{
        int clientSocket;
        short port;
        string ip;
        fd_set fd;
        struct timeval ti;

    public:
        Client_tcp(short port, string ip);

        void envoyer(string&);

        void recevoir(string&);

        ~Client_tcp();
};

#endif // CLIENT_TCP_H



client.cpp:

Code: [Select]
#include "client_tcp.h"

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

using namespace std;

Client_tcp::Client_tcp(short port, string ip):port(port), ip(ip)
{
    struct sockaddr_in serverAddr;

    if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) != -1)
    {
        printf("[+]Socket Creer.\n");

        FD_ZERO(&fd);
        bzero(&serverAddr, sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(port);
        serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());

        if((connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr))) != -1)
        {
            printf("[+]Connecter au Server.\n");
        }
        else
        {
            cout<<"connect erreur"<<endl;
        }

    }
    else
    {
        cout<<"sock erreur"<<endl;
    }

}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------


void Client_tcp::envoyer(string &rq)
{
    write(clientSocket, rq.c_str(), rq.size());
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------


void Client_tcp::recevoir(string &tram)
{
    char bef;

    ti.tv_sec=2;
    ti.tv_usec=0;
    FD_SET(clientSocket,&fd);
    if(select(clientSocket+1, &fd, NULL, NULL, &ti) == 1)
    {
        while (read(clientSocket, &bef, 1) == 1)
        {
            tram.append(&bef, 1);
        }
    }
    else cout<<"Deconecter"<<endl;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------

Client_tcp::~Client_tcp()
{
    close (clientSocket);
}




simulateur de la NodeMCU

serveur.cpp:


Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>


using namespace std;


int main()
{
int t,p,h,c;

int sock_serv;
struct sockaddr_in serveur;

int newclien;
struct sockaddr_in clien;

char bef;
char valeur[255];

socklen_t addr_size;

if((sock_serv = socket(AF_INET, SOCK_STREAM, 0)) != -1)
{
printf("[+]Server Socket Creer.\n");

bzero(&serveur, sizeof(serveur));
serveur.sin_family = AF_INET;
serveur.sin_port = htons(5000);
serveur.sin_addr.s_addr = inet_addr("127.0.0.1");

if((bind(sock_serv, (struct sockaddr*)&serveur, sizeof(serveur))) != -1)
{
printf("[+]Bind au Port 5000.\n");

listen(sock_serv, 5);
printf("[+]listen...\n");

while(1)
{
t = rand() % 100 + 1;
p = rand() % 100 + 1;
h = rand() % 100 + 1;
c = rand() % 100 + 1;

newclien = accept(sock_serv, (struct sockaddr*)&clien, &addr_size);

read(newclien, &bef, 1);
    cout<<bef<<endl;

if (bef == '?')
{
sprintf(valeur, "<Temperature>%d</Temperature><Pression>%d</Pression><Humidite>%d</Humidite><Courent>%d</Courent>", t,p,h,c);
cout << valeur << endl;
send(newclien, valeur, strlen(valeur), 0);
}
close(newclien);
}
}
else perror("bind:");
close(sock_serv);
}
else perror("socket:");
exit (0);
}

hbachetti

Pas de doute c'est bien du TCP.
Apparemment d'après ce que je vois ici : does-the-port-change-when-a-server-accepts-a-tcp-connection, sous Linux il n'y a pas de nouveau port alloué par accept(), simplement un nouveau handle (socket), d'où ma confusion.

Je ne connais pas cette partie sur ESP8266.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

B_Remi

OK merci quand même.


Merci c'est la première fois que je vois quelqu'un répondre aussi vite sur les forums.

hbachetti

J'ai la nette impression que je ne suis pas le seul  :)
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Go Up