Skocz do zawartości

Żonglowanie danymi ESP8266 poprzez HTTP klient - serwer.


Kucharskov

Pomocna odpowiedź

Witam!

Mam napisany własnoręcznie przykładowy kod serwera. Serwer stawia AP, na którym co sekundę zmienia sobie wartość zmiennej typu bool, a pod adresem dataserver.local wyrzuca ją w formie JSON: kod źródłowy serwera. Drugi ESP został oprogramowany jako klient - łączy się pod postawione AP. Ma on również odpytywać serwer poprzez wcześniej wspomniany adres i pobierać JSON (na razie) do zmiennej tekstowej: kod źródłowy klienta.

Kod napisany jest w miarę porządnie (pomijając delay w kliencie). Niestety nie mam pojęcia czemu klient zwraca ciągle: Error: connection refused. Trochę debugowałem kod i pomimo całej prawidłowości połączenia HTTP to zmienna httpCode ma wartość -1 jakby serwer nie odpowiadał klientowi. Adresy IP są z tej samej puli, bramy się zgadzają. O dziwo po podpięciu się telefonem pod AP serwera i wejściu na ustawiony adres serwer bez problemu odpowiada.

Może ktoś ma jakiś pomysł co może być nie halo?

Z góry dzięki!

Link do komentarza
Share on other sites

Problem częściowo rozwiązany. Okazało się, że klient po podpięciu pod serwer nie umiał rozszyfrować adresu mDNS "dataserver.local". Po milionach prób i ustawieniu zmiennej klienta z adresem na:

const char *url = "http://192.168.4.1/";

wreszcie zabanglało i pozwoliło przesyłać dane! Niestety średnio satysfakcjonuje mnie takie rozwiązanie, ponieważ jest mało przenośne. Serwer po to wystawiał mDNS aby klient mógł bez konkretnej znajomości adresu odczytać dane z serwera. Czy ma ktoś może z tutaj obecnych (jeżeli do jasnej cholery ktokolwiek mnie czyta bo to już 4 mój pusty temat) propozycję na wyciągnięcie adresu serwera aby móc go odpytać o dane? Może DHCP i brama domyślna? Tylko jak wtedy skleić z obiektu IPAddress taki ładny URL jak u góry? Bo klient HTTP jest dość wrażliwy na znaczki.

Link do komentarza
Share on other sites

A czemu mDNS a nie DNS? Do dwie zupełnie różne sprawy i resolver wcale nie musi się na obu znać. Masz przecież bibliotekę DNS na ESP, prawda (jeśli - jak raczyłeś się sam wyrazić - do jasnej cholery czytujesz czasami dokumentację zanim zaczniesz na forach d... zawracać) ?

A taki ładny adres... nie wiem czy zauważyłeś, ale IPAddress ma takie fajne metody jak fromString i toString, o nie chodzi?

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Wielkie dzięki za podrzucenie pomysłu z samym DNS. Było dość proste w implementacji, a dodatkowo serwer DNS może odpowiadać na wszystkie domeny dzięki drugiemu parametrowi ustawionemu na "*". Niestety klient wciąż nie wiem czemu nie potrawi rozwiązać serwowanej nazwy domeny. Próbowałem na miliony sposobów: domeny z końcówką .local .pl .com .org, z końcowym slashem i bez, z początkiem http i bez. Wciąż connection refused

Kod klienta: https://pastebin.com/F3Kmd16D

Kod serwera: https://pastebin.com/RvdWh4Ce

W kodzie klienta mam tam zakomentowany sposób na generowanie url z gateway'a. On działa, ale chciałem opanować od razu połączenie po nazwie domenowej. Oczywiście, żeby było wciąż zabawnie, po podłączeniu się telefonem pod sieć serwera z ustawioną "*", każdy adres jest poprawnie rozwiązywany i kierowany na stronę z danymi.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Na pierwszy rzut oka wszystko wygląda bardo ślicznie...

Ja bym sprawdził:

1) czy faktycznie klient wie jaki jest IP serwera DNS - WiFi.dnsIP();

2) jeśli wie, czy potrafi rozwiązać nazwę (dns_gethostbyname());

Niestety - mam tylko jedną wolną płytkę ESP, więc nie mam jak sprawdzić 😞

 

Link do komentarza
Share on other sites

Sprawdziłem zgodnie z zaleceniem:

1) WiFi.dnsIP() zwraca poprawny adres serwera DNS: 192.168.4.1

2) Nie mam bladego pojęcia jak wywołać podaną powyżej metodę. Może dlatego, że posiadam dokładnie płytkę NodeMCU, a nie czyste ESP8266. Podobno istnieje jakaś klasa DNSClient, która posiada metodę "getHostByName" ale nawet jej nie umiem w żaden sposób namierzyć aby ją wgrać do IDE i wrzucić w projekt.

Link do komentarza
Share on other sites

Wywołać po prostu - to nie jest metoda a funkcja.

NodeMCU to nic innego jak czyste ESP8266 nalutowane na jakiś kawałek laminatu ze ścieżkami i paroma innymi  drobiazgami.

Fragment mojego kodu:

    
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

extern "C" {
#include "user_interface.h"
#include "lwip/err.h"
#include "lwip/dns.h"
}

// dalej w jakiejśtam funkcji, zwracającej czy adres został rozwiązany

int getHostByNameA(const char *hostname)
{
    static ip_addr_t ipaddr;
    if (dns_status == 1 && millis() - last_dns_query < 10000UL) { // to takie prywatne...
        return 1;
    }
    dns_status = 0;
    resolvedHost = static_cast<uint32_t>(0);
    last_dns_query = millis();
    if (resolvedHost.fromString(hostname)) {
        dns_status = 2;
        return 0;
    }
    err_t err = dns_gethostbyname(hostname, &ipaddr, &dnsFoundCallback, NULL);
    if(err == ERR_OK) {
        resolvedHost = ipaddr.addr;
        dns_status = 2;
        return 0;
    }
    if (err == ERR_INPROGRESS) {
        dns_status = 1;
        return 0;
    }
    dns_status = 2;
    return 0;
}

 

Link do komentarza
Share on other sites

Wrzuciłem taki kodzik:

ip_addr_t ipaddr;
err_t err = dns_gethostbyname("dataserver.local", &ipaddr, NULL, NULL);
Serial.print("ERR_T: ");
Serial.println(err);
Serial.print("ip_addr_t: ");
Serial.println(ipaddr.addr);

W konsoli wypluło to:

ERR_T: -5
ip_addr_t: 4277137406

Niestety nie rozumiem nic z tego bo samo dns_gethostbyname jest tak niskopoziomowe że biegam po omacku nawet z dokumentacją.

Link do komentarza
Share on other sites

To teraz sobie przelicz na cztery bajty.

Niestety - jeśli chcesz cokolwiek robić z IPv4 musisz wiedzieć jak wygląda adres w różnych postaciach. W tym przypadku po konwersji na hex masz 0xfeefeffe - czyli na pewno nie to czego oczekiwałeś.

Ale - zaglądając sobie do definicji widzimy:

#define ESPCONN_INPROGRESS -5 /* Operation in progress    */

Czyli przekładając na ludzki język - klient wysłał żądanie do serwera, a serwer jeszcze nie odpowiedział.

Poczekaj sobie aż err zmieni się z ERR_INPROGRESS na jakąś inną wartość, dopiero wtedy możesz liczyć na jakąś sensowną wartość w ipaddr - lub na informację, że rozwiązanie adresu się nie powiodło.

 

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.