Forum: Mikrocontroller und Digitale Elektronik UDP Packete AVR NET IO


von Stefan (Gast)


Lesenswert?

Hallo Forum,

ich habe den Webserver von U Radig nach meinen Bedürfnissen angepasst 
und zum laufen gebracht.

Nun wollte ich einen Schritt weiter gehen und die Daten (Temperaturen 
etc.) per UDP auf meinen Rechner schicken.

Den "Server" am PC habe ich selbst programmiert und dieser funktioniert 
auch.
Leider stehe ich aber wo anders an.

In der Hauptschelife steht nun:
1
create_new_udp_packet((sizeof(eth_buffer)-1), 905, 904, IP(192,168,000,158));

Das AVRNETIO verbindet sich zwar mit meinem Server (Server zeigt mir 
seine IP und den Port an) aber ich weis nun nicht, wo ich meine Daten 
(Temperaturen etc.) einfügen muss.

Soweit ich herauslesen konnte, wird alles in eth_buffer geschrieben.
Quelladresse
Zieladresse
Länge des Datagrams
Opitonale Prüfsumme
Daten

Wie bekomme ich da meine Werte rein?
Habe eth_buffer[TCP_DATA_START] gefunden. Hat mich aber auch nicht 
weitergebracht.

Meine Ausgabe in C# sieht fürs erste so aus:
1
static void Main(string[] args)
2
        {
3
            int recv;
4
            byte[] data = new byte[1024];
5
           
6
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 904);
7
8
            Socket newSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
9
            newSocket.Bind(endpoint);
10
11
            Console.WriteLine("Waiting for a Client");
12
13
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 904);
14
            EndPoint tmpRemote = (EndPoint)sender;
15
16
            recv = newSocket.ReceiveFrom(data, ref tmpRemote);
17
18
            Console.WriteLine("Message received from {0}", tmpRemote.ToString());
19
            if (recv == 0)
20
            {
21
                Console.WriteLine("recv = 0");                 
22
            }
23
            Console.Write("Message: ");
24
            Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
25
                
26
            string welcome = "Welcome to my server!";
27
            data = Encoding.ASCII.GetBytes(welcome);
28
29
30
            if (newSocket.Connected)
31
            {
32
                Console.WriteLine("Debug - Verbindung besteht");
33
                newSocket.Send(data);
34
            }
35
36
37
            while (true)
38
            {
39
                if (!newSocket.Connected)
40
                {
41
                    Console.WriteLine("Client disconnected");
42
                    break;
43
                }
44
                //Console.WriteLine("Debug");
45
46
                data = new byte[1024];
47
                recv = newSocket.ReceiveFrom(data, ref tmpRemote);
48
49
50
                if (recv == 0)
51
                {
52
                    Console.WriteLine("recv = 0");
53
                    break;
54
                }
55
                Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
56
57
            }
58
            Console.Read();
59
            newSocket.Close();
60
            
61
        }


Der Fehler liegt bestimmt bei meiner unwissenheit aber würde mich 
dennoch um Hilfe freuen :)

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Schlauer geworden:
1
PROGMEM char http_header[]={"Test aaa bbb ccc"};
2
3
memcpy_P((char*)&eth_buffer[TCP_DATA_START_VAR],http_header,(sizeof(http_header)-1));

Immerhin gibt er mit "Test aaa bbb ccc" aus am Server aber leider auch 
einige andere Zeichen...

von foo (Gast)


Lesenswert?

Du sendest in deiner Hauptschleife den kompletten Buffer raus, inklusive 
den zufälligen Speicherinhalten die da vorher schon drin standen. 
"(sizeof(eth_buffer)-1)"

Dein String zusammen mit den zufälligen Zeichen wandert also so übers 
Netz und wird von der Gegenstelle korrekt ausgegeben.

von Stefan (Gast)


Lesenswert?

Also muss schauen ob noch irgendeine Methode eth-Buffer zugreift bzw 
diesen zuerst auf "0" setzen.

Frag mich nur ob das auch die richtige Art und Weise ist, wie man sowas 
angeht

von foo (Gast)


Lesenswert?

Nein. Du würdest dann eben noch zig Nullbytes hinterhersenden.

Merk dir, während du den Buffer vollschreibst, wie viel du davon 
beschrieben hast, und setze die Paketlänge entsprechend.

von Sascha W. (sascha-w)


Lesenswert?

Stefan schrieb:
> Schlauer geworden:
>
1
> PROGMEM char http_header[]={"Test aaa bbb ccc"};
2
> 
3
> memcpy_P((char*)&eth_buffer[TCP_DATA_START_VAR],http_header,(sizeof(http_header)-1));
4
>
>
> Immerhin gibt er mit "Test aaa bbb ccc" aus am Server aber leider auch
> einige andere Zeichen...

Wenn du UDP-Pakete sendest, dann musst du die Daten ab UDP_DATA_START.. 
reinkopieren, da der Header von TCP größer ist hast du sonst noch einige 
Bytes Daten, bevor Deine Nutzdaten kommen.

Sascha

von Stefan (Gast)


Lesenswert?

Hahhaha, ja das war wohl etwas naiv =)
UDP_DATA_START hat sehr geholfen!
1
PROGMEM char http_header[]={"Test aaa bbb ccc"};
2
3
memcpy_P((char*)&eth_buffer[UDP_DATA_START],http_header,(sizeof(http_header)-1));
4
  create_new_udp_packet((sizeof(eth_buffer)), 905, 904, IP(192,168,000,158));

Nun bekomme ich den String so wie er sein soll, allerdings mit 4 
absätzen!

Des weiteren ist mir noch nicht ganz klar, wie ich zB ein int array nun 
in eth_buffer bekomme!

Mein Gedanke:
1
nsigned int var_array[MAX_VAR_ARRAY] = {10,50,30,0,0,0,0,0,25,0,10,14,38,42,30,34,0,0,750,750,12,0,12,0,0,0,0,0,0,0};
2
char Data_Buffer[MAX_VAR_ARRAY];
3
4
itoa (var_array,Data_Buffer,10);
5
  int str_len = strnlen(Data_Buffer,MAX_VAR_ARRAY);
6
  memmove(&eth_buffer[UDP_DATA_START],Data_Buffer,str_len);
7
        
8
  memcpy_P((char*)&eth_buffer[UDP_DATA_START],Data_Buffer,(sizeof(Data_Buffer)));  
9
  create_new_udp_packet((sizeof(eth_buffer)), 905, 904, IP(192,168,000,158));
Gibt aber nichts vom var_array aus...

Aber schonmal weiter :D

Bis morgen, gute nacht und Danke!

von foo (Gast)


Lesenswert?

Stefan schrieb:
> Nun bekomme ich den String so wie er sein soll, allerdings mit 4
> absätzen!

"Absätzen"??

> itoa (var_array,Data_Buffer,10);

itoa's erstes Argument ist ein Integer und kein Integer Array. Was da 
konvertiert wird ist die Adresse von diesem Array. Die steht für 
gewöhnlich in keinem sinnvollen Zusammenhang zu dem Inhalt des Arrays...

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Hahhaha, ja das war wohl etwas naiv =)
> UDP_DATA_START hat sehr geholfen!
>
>
1
> PROGMEM char http_header[]={"Test aaa bbb ccc"};
2
> 
3
> memcpy_P((char*)&eth_buffer[UDP_DATA_START],http_header,(sizeof(http_header)-1));
4
>   create_new_udp_packet((sizeof(eth_buffer)), 905, 904, 
5
> IP(192,168,000,158));
6
>
>
> Nun bekomme ich den String so wie er sein soll, allerdings mit 4
> absätzen!

Ich versteh gar nicht, was da drann so schwer zu verstehen ist.

eth_buffer hat eine Größe in Bytes
1
  +--+--+--+--+--+--+--+--+--+--+--+--+--+
2
  |  |  |  |  |  |  |  |  |  |  |  |  |  | 
3
  +--+--+--+--+--+--+--+--+--+--+--+--+--+

von diesen Bytes geht ein Anteil für den Paket-Header drauf
1
  +--+--+--+--+--+--+--+--+--+--+--+--+--+
2
  |HH|HH|HH|  |  |  |  |  |  |  |  |  |  | 
3
  +--+--+--+--+--+--+--+--+--+--+--+--+--+

und dann schreibst du noch ein paar Nutzdaten ins Paket
1
  +--+--+--+--+--+--+--+--+--+--+--+--+--+
2
  |HH|HH|HH|DD|DD|DD|DD|  |  |  |  |  |  | 
3
  +--+--+--+--+--+--+--+--+--+--+--+--+--+

und wenn es dann zum versenden des Pakets kommt, dann
1
  +--+--+--+--+--+--+--+--+--+--+--+--+--+
2
  |HH|HH|HH|DD|DD|DD|DD|  |  |  |  |  |  | 
3
  +--+--+--+--+--+--+--+--+--+--+--+--+--+
4
5
  | ----------- sizeof eth_buffer -------|
versendest du den kompletten Buffer als ganzes und wunderst dich, dass 
da hinten an deine Nutzdaten drann noch etwas im Paket steht, dass du 
nicht hineingeschrieben hast.

Ernsthaft?
Das verwundert dich?

> Des weiteren ist mir noch nicht ganz klar, wie ich zB ein int array nun
> in eth_buffer bekomme!

Vielleicht solltest du erst mal C lernen, ehe du dich an diesen ziemlich 
simplen Dingen versuchst?

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

=)

Alles klar nun funktioniert es, dass ich meine UDP Packete bekomme!
Das ganze ohne unnötigen Zeichen und Absätzen.

Naja C lernen... das Problem ist, dass ich nicht regelmäßig programmiere 
und deswegen immer wieder etwas auffrischen muss!

Für Euch bestimmt mühsam aber dennoch vielen Dank für Eure hifle :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.