FileRead() vs. TCP/IP-Server

  • Hi zusammen,

    ich habe mal eine - vielleicht etwas ungewöhnliche - Frage: ich möchte eine Zustandsinformation (offen, geschlossen, unbekannt) im Netzwerk verteilen. Diverse Clients sollen diese Information immer ziemlich aktuell (Minimum: 10sek, Maximum: 1min) zur Verfügung haben. Gespeichert wird die Information zentral (auf dem Server) in einer Text-Datei. Geschrieben wird die Information ca. 5 mal am Tag, und zwar von beliebigen Clients.

    Bisher habe ich es so gelöst, dass die Clients sich die Information über ein FileRead() aus dem freigegebenen Verzeichnis vom Server holen (und auch dort schreiben). D.h. die Datei wird also z.B. bei 3 Clients / 30s-Taktung insgesamt 6 mal pro Minute gelesen. Bei 1440min am Tag sind das 8640 lesenden Dateizugriffe auf dem Server pro Tag.

    Nun habe ich mir überlegt, dass ich das vielleicht über einen TCP-Server geschickter lösen könnte. Einen Programm, welches die Information unter der Lokalen IP-Adresse (Port 80) des Servers bereitstellt und die Information auch entgegen nehmen /schreiben kann, habe ich bereits programmiert (besser: umgeschrieben, gezeigt wie es geht wurde es hier im Forum):

    Spoiler anzeigen
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_icon=
    #AutoIt3Wrapper_outfile=
    #AutoIt3Wrapper_UseX64=n
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

    [/autoit] [autoit][/autoit] [autoit]

    ;========================================== Includes und Optionen =============================================================================================
    #include-once
    #include <Misc.au3>

    [/autoit] [autoit][/autoit] [autoit]

    If _Singleton("share_status_server", 1) = 0 Then
    Msgbox(0,"Warnung","Eine Instanz des Skripts wird bereits ausgeführt!")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Funktion welche beim Beenden ausgeführt wird
    OnAutoItExitRegister("OnAutoItExit")

    [/autoit] [autoit][/autoit] [autoit]

    ;-----------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    ;Zum Start den zulezt gespeicherten Zustand aus der Datei lesen
    Global $status = FileRead(@ScriptDir & "\status.txt")
    If $status = "" Then $status = "unbekannt"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    TCPStartup()
    $MainSocket = TCPListen(@IPAddress1, 80)

    [/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    ;Lauschen
    Do
    $socket = TCPAccept($MainSocket)
    Sleep(100)
    Until $socket <> -1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Empfangen
    $sRecv = ""
    Do
    $sRecv &= TCPRecv($socket, 1)
    Until StringInStr($sRecv, @CRLF & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Auswerten
    ConsoleWrite($sRecv & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    If StringInStr($sRecv, "GET /get_status") Then
    HTTPSend($socket, $status)

    [/autoit] [autoit][/autoit] [autoit]

    ElseIf StringInStr($sRecv, "GET /set_status=offen") Then
    HTTPSend($socket, "ok")
    $status="offen"

    [/autoit] [autoit][/autoit] [autoit]

    ElseIf StringInStr($sRecv, "GET /set_status=geschlossen") Then
    HTTPSend($socket, "ok")
    $status="geschlossen"

    [/autoit] [autoit][/autoit] [autoit]

    ElseIf StringInStr($sRecv, "GET /set_status=unbekannt") Then
    HTTPSend($socket, "ok")
    $status="unbekannt"

    [/autoit] [autoit][/autoit] [autoit]

    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Verbindung schließen
    TCPCloseSocket($socket)
    $socket = -1

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    TCPShutdown()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;-------------------------------------------------------------------------
    Func HTTPSend($socket, $sData)
    $sHeader = "HTTP/1.1 200 OK" & @CRLF & _
    "Server: Autoit" & @CRLF & _
    "Cache-Control: max-age=0, public" & @CRLF & _
    "Connection: close" & @CRLF & _
    "Content-Length: " & StringLen($sData) & @CRLF & _
    "Content-Type: text/html; charset=UTF-8" & @CRLF & @CRLF
    Return TCPSend($socket, $sHeader & $sData)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;-------------------------------------------------------------------------
    Func OnAutoItExit()

    [/autoit] [autoit][/autoit] [autoit]

    ;Zustand speichern
    FileDelete(@ScriptDir & "\status.txt")
    FileWrite(@ScriptDir & "\status.txt", $status)

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit]

    Den auslesenden Teil für die Clients will ich über die IE.au3 machen: _IENavigate() bzw. _IEBodyReadHTML().

    Spoiler anzeigen
    [autoit]

    #include-once
    #include "IE.au3"
    #include <Misc.au3>

    [/autoit] [autoit][/autoit] [autoit]

    If _Singleton("share_status_client", 1) = 0 Then
    Msgbox(0,"Warnung","Eine Instanz des Skripts wird bereits ausgeführt!")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Internet-Explorer starten (unsichtbar)
    _IEErrorHandlerRegister ()
    $oIE = _IECreate("about:blank", 0, 0, 1, 0)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Zyklisch die Information abrufen
    While 1

    [/autoit] [autoit][/autoit] [autoit]

    _IENavigate($oIE, "http://IP-ADRESSE-DES-SERVERS/get_status", 1) ; --> Beim Testen wohl auch einfach @IPAddress1
    $status = _IEBodyReadHTML($oIE)
    MsgBox("", "", $status, 3)

    [/autoit] [autoit][/autoit] [autoit]

    Sleep (5000)
    WEnd

    [/autoit]

    Nun also endlich die Frage(n).

    1. Haltet ihr es generell für sinvoll den Weg über einen TCP-Server zu gehen, oder sagt ihr: "Pfeif auf die paar Plattenzugriffe..." :P ?
    2. Wenn das Server-Programm einmal gestartet ist, finden dann eigentlich trotzdem noch irgendwelche Plattenzugriffe statt die ich zwar nicht programmiert habe, die aber Autoit/Windows für den Serverbetrieb benötigt?
    3. Wie sieht das beim den Clients aus? Erzeugt das Plattenlast (ich habe den Eindruck, ich höre meine Platte bei jedem Loopdurchlauf, also alle 5sek rattern) ?( ...

    Danke für eure Meinungen
    Gruß Trainer

  • Du könntest auch direkt per HTTP mit einem PHP Script o.Ä. auf deinem Server kommunizieren. Das geht auch über TCP und über Google gibt es sogar einige Tutorials für die Verwendung von HTTP in AutoIt. So wirst du vermutlich auch auf keine Probleme was Firewalls etc. betrifft stoßen.

  • Das Netzwerk ist mein eigenes, hier zuhause. Der Server ist auch nur ein Win7-Rechner, der halt als Server dient (Anrufbeantworter, Fax, Email, etc.). Firewalls sind also kein Problem.

    Einen XAmpp o.Ä. wollte ich darauf jetzt nicht unbedingt installieren. Oder habe ich dich falsch verstanden?

  • Zitat

    Das Netzwerk ist mein eigenes, hier zuhause. Der Server ist auch nur ein Win7-Rechner, der halt als Server dient (Anrufbeantworter, Fax, Email, etc.)


    Da hab ich dich falsch verstanden ^^. Ich dachte du hättest nur einen VServer bei irgendeinem Anbieter gemietet (funpic oder sowas).

    Zitat

    Haltet ihr es generell für sinvoll den Weg über einen TCP-Server zu gehen, oder sagt ihr: "Pfeif auf die paar Plattenzugriffe..." :P ?


    Ich würde es mit TCP machen... Das ist schneller und in dem Fall vermutlich auch sinnvoller.

    Zitat

    2. Wenn das Server-Programm einmal gestartet ist, finden dann eigentlich trotzdem noch irgendwelche Plattenzugriffe statt die ich zwar nicht programmiert habe, die aber Autoit/Windows für den Serverbetrieb benötigt?


    Eigentlich nicht... Die Daten stammen ja dann direkt aus dem Arbeitsspeicher.

    Zitat

    Den auslesenden Teil für die Clients will ich über die IE.au3 machen: _IENavigate() bzw. _IEBodyReadHTML().


    Wozu? Ich dachte du willst die Daten direkt über TCP auslesen. ?(

  • Zitat

    Wozu? Ich dachte du willst die Daten direkt über TCP auslesen.


    Da hast du eigentlich Recht, ich denke ich werde mich da morgen noch mal dransetzen, und es direkt über TCP machen. Bin nur zu müde jetzt..

    :sleeping:
    Gruß
    Trainer