TCP/IP Socket-Server mit dem Microframework (Netduino)

    • VB.NET

    Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von gfcwfzkm.

      TCP/IP Socket-Server mit dem Microframework (Netduino)

      Hallo,

      Ich wollte einen einfachen TCP/IP Server zeigen, der richtig wenig Platz braucht. Der Server erfordert das Microframework. Ich habe alles mit dem Netduino Plus getestet. Ein Server mit nur 7.1x5.3x1.3cm (BxLxH) den man auch für Aktivierungen oder sogar als Webserver ummodifizieren kann.

      Hier den Server:

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Imports System
      2. Imports System.Text
      3. Imports System.Net
      4. Imports System.Net.Sockets
      5. Imports System.Threading
      6. Imports Microsoft.SPOT
      7. Imports Microsoft.SPOT.Hardware
      8. Imports SecretLabs.NETMF.Hardware
      9. Imports SecretLabs.NETMF.Hardware.NetduinoPlus
      10. '(C) 2013 Pascal Gesell @ gfcwfzkm
      11. 'Socket-Server
      12. Module Module1
      13. Private socket As Socket = Nothing
      14. Private onb As New OutputPort(Pins.ONBOARD_LED, False)
      15. Sub Main()
      16. Debug.EnableGCMessages(True)
      17. 'Eigene IP ausgeben
      18. If System.Diagnostics.Debugger.IsAttached Then 'Überprüft, ob er im Debug-Modus ist
      19. ' Locale IP-Adresse Anzeigen (Nur im Debug-Mode)
      20. Dim Ips() As Microsoft.SPOT.Net.NetworkInformation.NetworkInterface = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
      21. For i As Integer = 0 To Ips.Length - 1 'Solange durchgehen, bis die IP nicht 0.0.0.0 lautet
      22. If System.Diagnostics.Debugger.IsAttached Then Debug.Print("Netduino-IP:" & Ips(i).IPAddress.ToString())
      23. Next
      24. End If
      25. 'Socket Class initialisieren
      26. socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
      27. 'Abhörport wählen (Im Moment 80)
      28. socket.Bind(New IPEndPoint(IPAddress.Any, 9999))
      29. 'Anfragen-Listen starten
      30. socket.Listen(10)
      31. While True
      32. Using clientSocket As Socket = socket.Accept()
      33. 'Client-IP bekommen
      34. Dim clientIP As IPEndPoint = TryCast(clientSocket.RemoteEndPoint, IPEndPoint)
      35. Dim clientEndPoint As EndPoint = clientSocket.RemoteEndPoint
      36. 'int byteCount = cSocket.Available;
      37. Dim bytesReceived As Integer = clientSocket.Available
      38. If bytesReceived > 0 Then
      39. 'Empfangene Daten verarbeiten
      40. Dim buffer As Byte() = New Byte(bytesReceived - 1) {}
      41. Dim byteCount As Integer = clientSocket.Receive(buffer, bytesReceived, SocketFlags.None)
      42. Dim request As New String(Encoding.UTF8.GetChars(buffer))
      43. Debug.Print("Free RAM: " + Microsoft.SPOT.Debug.GC(False).ToString + " Bytes" + Constants.vbCrLf + "Anfrage von: " + clientIP.ToString + Constants.vbCrLf + request)
      44. If request.ToUpper = "TOGGLE" Then
      45. onb.Write(Not onb.Read())
      46. request = "TOGGLE LED"
      47. Else
      48. request = request
      49. End If
      50. clientSocket.Send(Encoding.UTF8.GetBytes(request), request.Length, SocketFlags.None)
      51. End If
      52. End Using
      53. End While
      54. End Sub
      55. End Module


      Und ein Client zum testen

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Imports System.Net.Sockets
      2. Imports System.Text
      3. Imports System.Net
      4. Module Module1
      5. Dim x As String
      6. Sub Main()
      7. Dim client As Socket
      8. Console.Title = "Netduino Socket-Programm"
      9. Dim ip As String
      10. Dim port As String
      11. Console.WriteLine("Bitte IP-Adresse eingeben.")
      12. ip = Console.ReadLine().Trim
      13. Console.WriteLine("Bitte Port eingeben")
      14. port = Console.ReadLine().Trim
      15. While (1)
      16. x = Console.ReadLine()
      17. If Not x.Trim = Nothing Then
      18. If x.ToUpper = "$EXIT" Then
      19. End
      20. Else
      21. Dim Data As Byte() = Encoding.ASCII.GetBytes(x) 'Daten (String) in (ASCII)Bytes konvertieren
      22. Try
      23. client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
      24. Dim portSelect As Integer = Convert.ToInt16(port) 'String "port" zum Integer "portSelect" konvertieren
      25. client.Bind(New IPEndPoint(IPAddress.Any, 9998)) 'Empfangs-Settings (Port&IP)
      26. Dim remoteIPAddress As System.Net.IPAddress = System.Net.IPAddress.Parse(ip) 'Ziel-IP
      27. Dim remoteEndPoint As New System.Net.IPEndPoint(remoteIPAddress, portSelect) 'Ziel-Port
      28. Console.WriteLine("Sende: " + x)
      29. client.Connect(remoteEndPoint) 'Zum Netduino verbinden
      30. client.Send(Data) 'Daten senden
      31. Dim bytesReceived As Integer 'Empfangsvariable
      32. While (Not bytesReceived > 0)
      33. bytesReceived = client.Available
      34. End While
      35. Dim buffer As Byte() = New Byte(bytesReceived - 1) {}
      36. Dim byteCount As Integer = client.Receive(buffer, bytesReceived, SocketFlags.None)
      37. Dim received As New String(Encoding.ASCII.GetChars(buffer))
      38. Debug.Print(received & vbCrLf & received.Length)
      39. Console.WriteLine("Empfangen: " + received)
      40. client.Close()
      41. Catch ex As Exception
      42. Print(ex.ToString, ConsoleColor.Red)
      43. End Try
      44. End If
      45. End If
      46. x = Nothing
      47. End While
      48. End Sub
      49. End Module


      Man kann bei Port9999 auch den Webbrowser benutzen.

      mfg

      gfcwfzkm

      PS: Client und Server-Code wurde geändert. Server: Besserer IP-Check. Client: Kein GoTo + $EXIT-Command

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „gfcwfzkm“ ()

      sry: Offtopic:

      gfcwfzkm schrieb:

      Der Code darf ohne meine Genehmigung nicht anderweitig publiziert werden!
      Muß das denn immer sein?
      Meinst du denn, dein Code sei so kostbar, unds wär schlimm, wenn jmd anners sich mit diesen "Loorbeeren" schmücken täte?

      Mir ist auf Anhieb nur das Goto im Client aufgefallen, und mit solch "Loorbeeren" will sich eh niemand schmücken, und wird auch dem anneren Code gegenüber mißtrauisch.

      Und auch der Server - mangels Threading kann sich ja nur ein einziger Client mit diesem Server verbinden - dann hängt der Server in einem Dauerloop, wo kein 2. Client je einen Fuß dazwischenkriegt.
      Also so siehts mir jdfs. aus, ungetesteterweise, ist ja kein Test-Projekt dabei.

      Und überhaupt: das KnowHow für deinen Netduino-Server, und auch deine Programmierkenntnisse insgesamt hast du doch zum großen Teil erst hier auf VBP dir erworben - wieso jetzt kleinkarierte Bedingungen stellen, wenn du mal ein bischen davon zurückgibst?
      Zur ersten Frage: Nein, hätte nichts dagegen. Hab ich schon geändert...

      Zum 2.ten Satz: Es ist nur ein schnellgecodeter Test-Client. Wie gesagt kannst du auch dein Webbrowser zum probieren benutzten, wenn dir das lieber ist. Ich werde den Client-Code aber heute Abend verbessern. Ich gib zu, das Goto nicht hübsch ist.

      Zum 3.ten Satz: Auch wieder mal falsch. Ich rede hier vom Microframework. Die Microsoft-Jungs haben Threading Softwäremässig implementiert. Du kannst auf MCU's mit dem Microframework in C# oder VB mehrere Threads erstellen, obwohl der MCU dies Hardwaremässig nicht unterstüzten würde. Für mehr Infos siehe den Wikipedia Eintrag. Und wenn ein Netduino Plus (48Mhz, ARM7) nicht reicht, kann man den neueren Netduino Plus 2 (168Mhz, Cortex-M4) verwenden oder andere...

      Und zum Knowhow: Ja, ich habe ein paar Sachen hier vorher im Forum angefragt (Socket-Thread von mir). Und naja, wollte mit dem hier mal etwas zurückgeben. Ein Server auf einem 0.75W-Board.

      mfg

      gfc
      Jou - also jetzt nach meim Gemecker wirklich vielen Dank, in mehrfacher Hinsicht.
      Weil auch wenn ichs mir nicht anmerken lasse: Ich schätze das wirklich sehr hoch, dass jmd (nämlich du) tatsächlich etwas mit-teilst von dem KnowHow, was du dir erarbeitet hast.
      Das würde ich mir viel mehr wünschen, mit Seitenblick auf den ShowRoom, wo ja eigentlich keinerlei KnowHow geteilt wird, sondern mit immer Pochen auf Dekompilier-Verbot und CopyRights wird da gewissermaßen peepshow-mäßg Knowhow zwar gezeigt, aber nicht geteilt.
      Und auch wenn Netduino garnet mein Metier ist, habich hier immerhin gelernt, dass Netduino doch ziemlich ganz anners tickt, als wo ich üblicherweise unterwegs bin.
      So, Goto ist weg und eine anständige IP-überprüfung wurde in den Server eingebaut.

      @ErfinderDesRades Ja, habe mit dem Netduino die Welt der Microcontroller entdeckt. Ich finde es für VB/C#-Programmierer als Anfang deutlich besser als Arduino und Co. Vorallem weil es auch die Arduino-Shields unterstützt ^^
      Korrigiere mich, wenn ich falsch liege, aber ich werfe jetzt einfach mal das in den Raum, was mir gerade durch den Kopf gegangen ist:
      Socke.Available gibt die Datenmenge an, die über das Netzwerk empfangen wurde. Und zwar genau zum dem Zeitpunkt, zu dem es aufgerufen wird. Es wartet nicht. Wenn also jemand eine langsame Verbindung hat, dann kann es sein, dass noch nicht alles angekommen ist und dein Server verarbeitet nur den halben Teil der Datenmenge, also z.B. "TOGG". Der Rest kommt erst danach an. Sollte man nicht lieber daher ein Befehlsabschlusszeichen haben? Also das gelesen wird bis dieses Zeichen kommt und dann erst wird ausgewertet?
      Ich bezweifle das jemand so eine schwache Leitung hat ^^ Bei deinem Beispiel werden ja nur 6 Bytes verschickt. Wenn du nicht probierst, 8KByte auf einmal zu verschicken, kann dein Fall durchaus auftreten. Aber bei Daten unter 1kByte bin ich mir sicher, das dort nix verloren geht. Habe zum Testen mal eine 819Byte-Anfrage gesendet (Mit Firefox):
      Spoiler anzeigen
      GET /aaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbb/cccccccccccccccccccccccc/dddddddddddddddddddddd/eeeeeeeeeeeeeeeeeeeee/fffffffffffffffffffffffffff/ggggggggggggggggggggggg/hhhhhhhhhhhhhhhhhhhhh/iiiiiiiiiiiiiiiiiiiiiiiiiii/jjjjjjjjjjjjjjjjjjjjjjjjjjj/kkkkkkkkkkkkkkkkkkkk/llllllllllllllllllllll/mmmmmmmmmm/nnnnnnnnnnnnnnn/ooooooooooooooo/ppppppppppppppppp/qqqqqqqqqqqqqqqqqq/rrrrrrrrrrrrrrrrrrrr/sssssssssssssss/ttttttttttttttttt/uuuuuuuuuuuuu/vvvvvvvvvvvvvvv/wwwwwwwwwwww/xxxxxxxxxxxxxxx/yyyyyyyyyyyyyyy/zzzzzzzzzzzzzzz HTTP/1.1
      Host: 172.17.0.129
      User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
      Accept-Encoding: gzip, deflate
      Connection: keep-alive

      Hat er Problemlos verarbeitet.

      mfg

      gfc