Socketserver in GCC für RPi

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Guten Morgen,
    ich möchte für meinen RPi ein Socket-Server in C schreiben, der folgende Aufgaben erfüllen muss und von einem PHP-Client kontaktiert wird

    Überwachung von ttyAMA0
    Befehler vom RS485-Bus empfangen
        
    Verbindungen vom PHP-SocketClient akzeptieren
    Message einlesen
    Prüfen bzw. interpretieren
    Message via ttyAMA0 senden
    Auf Antwort ttyAMA0 warten
    Antwort an SocketClient senden
    nächste Message Einlesen
    wie vor
            
    Daraus ergeben sich u. A. folgende Fragen/Anforderungen

    • Der SocketServer und ttyAMA0-Server dürfen das Programm nicht blockieren, wie sind die optimalen Einstellungen insbesonder für den Socketserver, bei ttyAMA0 habe ich das im Griff
    • Wie erkenne ich, dass der Client nach der letzten Message aufgelegt hat
    • read setzt z. Zt. offenbar nicht die errno sondern liefert nur die Anzahl der gelesenen Zeichen zurück. Das nutze ich z. Zt. als Zeichen, dass der Client aufgelegt hat. Stimmt das oder mache ich etwas falsch?
    • kann ich beim Socketserver (insbesonder beim Accept und Read TimeOuts nutzen und wie stelle ich sie ein. Bei ttyAMA0 hat es gklappt. Steht das im Widerspruch zu nichtblockierenden Sockets?
    • Was genau ist zu tun, um aus dem C-Programm ein Daemon zu machen
    • sind tcp-Sockets oder udp bei diesen Anforderungen besser.

    Insgesamt habe ich bereits einen Code, der nur unvollkommen funktioniert und würde das gern mit eurer Hilfe absolut wasserdicht machen und bin für jede Unterstützung dankbar. Die Hinweise und Bespiele im Netz habe ich natürlich gesichtet. Bislang habe ich nur Beispiele gefunden, die das Verfahren grundsätzlich erklären.

    mfg
    uli

  • Hallo Ulipie,

    das ist alles zu machen, aber es gibt viel Arbeit. ;)

    Wenn ich das richtig verstehe, soll alles synchron laufen, also
    PHP -> Server -> ttyAMA0 -> anderes Geraet -> ttyAMA0 -> Server -> PHP.

    Kann PHP ueberhaupt UDP ? TCP kann es, das weiss ich.

    > Der SocketServer und ttyAMA0-Server dürfen das Programm nicht blockieren
    Sollen das zwei verschiedene Prozesse sein ?
    Wie laeuft dann die Kommunikation zwischen denen ?

    > Wie erkenne ich, dass der Client nach der letzten Message aufgelegt hat
    Bei UDP gar nicht, bei TCP liest man 0 Bytes vom Socket

    > kann ich beim Socketserver (insbesonder beim Accept und Read TimeOuts nutzen und wie stelle ich sie ein.
    man select

    > Was genau ist zu tun, um aus dem C-Programm ein Daemon zu machen
    Es braucht keinen Daemon, das kann ein normaler Prozess sein.

    Und wenn es unbedingt ein Daemon sein soll, wuerde ich das auf spaeter verschieben.
    VIEL spaeter ...

    > sind tcp-Sockets oder udp bei diesen Anforderungen besser.
    UDP ist einfacher: ein Paket kommt rein, die Groesse ist bekannt, keine Verbindung

    ]TCP ist aufwendiger: die Verbindung kommt zustande, Daten kommen an, Verbindung bricht ab.
    Um es sauber zu machen, muss der Server mehrere Verbindungen gleichzeitig zulassen und
    die Daten der Verbindungen sauber auseinanderhalten.

    Weil TCP wie ein Stream aussieht, gibt es auch keine klaren Grenzen der Blocks, das
    muss das Protokoll definieren.

    TCP ist dafuer gesichert, man weiss, dass einer dran ist und dass die Daten nur einmal
    und in der richtigen Reihenfolge ankommen.

    -> Google: Verbindungslos - Verbindungsorientiert

    Einmal editiert, zuletzt von Tell (30. Januar 2014 um 12:08)

  • Hallo Tell,
    deine Antworten helfen mir. Ich bleibe bei TCP. Die Funktionalität soll in einem Prgramm bleiben, ich glaube es ist einfacher. Das Auflegen erkenne ich schon an der leeren Msg beim read. Das entspricht auch deinem Hinweis und ist nun für mich ok. Selct scheint beim Accept Anwendung zu finden. Was ist aber, wenn ich im read bin und der Client schickt nichts mehr. Bei meinen Versuchen führte das zum Blockieren. Wie schütze ich mich davor? Ich hatte gedacht, hier hilft ein TimeOut????????????
    mfg
    uli

  • Hallo Ulipie,

    select uebergibt man ALLE Filedescriptoren. Also den fuer ttyAMA0, den Server-Socket
    und auch alle Sockets der Client-Verbindungen.

    Wenn einer davon aktiv wird, kommt select zurueck, und mit dem Set kann man herausfinden,
    welche aktiv geworden sind.

    => Es braucht also eine Liste aller aktiven Client-Verbindungen, erstens mal um die Filedescriptoren
    zu haben, aber auch einen Buffer pro Verbindung.

    select hat zwar ein Timeout, aber das tritt nur ein, wenn in der angegebenen Zeit keine
    Aktivitaet auf den ueberwachten Descriptoren war. Je nach den Anforderungen braucht
    es also noch weitere Mechanismen zur Ueberwachung von Timeouts.

  • Moin,

    da hilft imho nur: multithreading und asynchrone sockets.
    Ich fürchte, sonst wirst Du Deines Lebens nicht froh ...
    Aufsatzpunkt bei TCP ist üblicherweise der accept, der dann einen neuen socket hat und dann mit dem weggeforkt wird.
    Bei rs232 Verbindungen mach man das in der Regel über einen SIG_IO ...

    Poll ist bei mehreren Verbindungen imho absolut keine Option ...

    cu,
    -ds-

  • Hallo Forum,

    ich glaube, dass Problem ist mit der Unterstützung von Tell gelöst. Danke für die Hilfe. Wenn Interesse besteht, kann ich gern berichten und den code weitergeben.
    mfg
    uli

    Ich sehe jetzt erst die Antworten auf meine Frage. Mein Dank gilt natürlich allen.
    uli

    Einmal editiert, zuletzt von ulipie (31. Januar 2014 um 14:56)

  • Guten Morgen,

    ja, ich stelle gern meine bisherige Testversion zur Verfügung. Für Hinweise zur Verbesserung bin ich dankbar.

    http://www.piechnick.de/cms/socketserver.html

    Ich habe die aktuelle Version in meine Website kopiert. Achtung! die Seite ist veraltet, es gibt viele neue Entwicklungen. Für die nächsten Wochen nehem ich mir vor, hier Ordnung zu schaffen und die Darstellung meiner Hard- und Software zu aktualisieren.

    Das Projekt stellt sehr hohe Ansprüche an Zeit und KnowHow. ich schaffe es allein kaum noch. Vielleicht findet sich ja jemand, der mich dabei unterstützt, das Ganze weiter nach vorne zu bringen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!