Mit Steuergerät über Sockets kommunizieren

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Armend
User
Beiträge: 22
Registriert: Mittwoch 11. April 2018, 11:59

Hallo liebe Helfer,

könnte mir jemand bitte zum folgenden Thema helfen?

An meinen Rechner ist ein Steuergerät angeschlossen. Es handelt sich um eine LAN-Verbindung über Ethernet-Ports (IPv4).
Steuergerät (IP:169.254.10.112,PORT:6805) ------------------ Rechner (IP:169.254.10.113,Subnetzmaske:255.255.255.0)

Mein Python-Code läuft auf meinen Rechner.
Ziwschen dem Steuergerät und dem Rechner läuft eine Kommunikation (Diagnose) -> es werden Daten transportiert.

Mein Ziel:
Ich möchte die Daten, die das Steuergerät an den Rechner schickt, mit Python empfangen.
Ich dachte mir, dass ich lediglich ein Socket zu meinen eigenen Rechner (zum Ethernet-Anschluss IP 169.254.10.113) herstellen muss. Wenn die Daten vom Steuergerät am Rechner ankommen, müssen diese sicherlich auch über Python aufrufbar sein.

Mein Code:
###Client
import socket
socket_handler = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
IP = "169.254.10.113"
PORT = 65432 #Am Rechner sehe ich nur die Subnetzmaske. Als Port habe ich einfach mal 65432 genommen
socket_handler.settimeout(20)
try:
socket.connect()
data, addr = socket_handler.recv(1024)
print (data)
socket.close()
except socket.error as e:
print (e)



Fehlermeldung: Der Zielcomputer verweigerte die Verbindung (Errno 10061)


Geht das überhaupt, was ich versucht habe? Kann ich ein Socket zu meinen eigenen Ethernet-Anschluss erzeugen?
Ich möchte eigentlich nur mit dem Steuergerät kommunizieren (erstmal was einfaches -> z.B. Diagnose-Botschaften empfangen).


Viele Grüße
Armend
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Beschäftige dich mit dem grundlegenden Thema Netzwerkkomunikation.
Es gibt einen Server, der an einem Port lauscht und auf eine eingehende Verbindung wartet.
Die Verbindung wird dann vom Client angefragt, worauf eine bidirektionaler Kommunikationsweg aufgebaut wird.

Ich bin mir ziemlich sicher, dass dein PC nicht der Server ist.
Und einen Port rät man auch nicht, sondern man muss schon den nehmen, auf dem der Server eine eingehende Verbindung erwartet.

Es gibt Tools, die dir helfen Netzwerkoprotokolle zu loggen. Wireshark ist so ein Programm.
Benutzeravatar
__blackjack__
User
Beiträge: 13073
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Armend: Die Fehlermeldung glaube ich Dir nicht, denn da kommt gar kein Verbindungsversuch zustande, da das `socket`-Modul kein `connect()` kennt. Das gibt einen `AttributeError`. Bitte immer Code und Fehlermeldungen zeigen die auch tatsächlich zusammen gehören.

`socket_handler` ist kein passender Name für ein `socket`-Objekt. Wenn man das `r` am Ende weglassen würde, dann hätte man zumindest einen Namen der in einigen anderen Programmiersprachen Sinn machen würde. C zum Beispiel. Aber in Python ist das nicht einfach nur ein Handle, sondern ein komplettes Objekt das ein `socket` repräsentiert. Da sich beim `socket`-Modul nicht an die eigenen Namenskonventionen gehalten wurde, kann man das Objekt leider nicht `socket` nennen ohne mit Modul und/oder dem darin definierten Datentyp `socket` in Konflikt zu geraten. Man müsste da also noch etwas dran pappen. Zum Beispiel in dem man es `client_socket` nennt.

Die Ausnahmebehandlung macht keinen Sinn. Du ersetzt da einen kompletten Traceback, der zur Fehlersuche sehr sinnvoll ist, einfach durch die letzte Zeile von dem was man ohne diese Behandlung bekommen würde. Man weiss dann also welche Socket-Ausnahme ausgelöst wurde, muss aber raten in welcher Zeile das passiert ist. Wenn man mit Ausnahmen nichts sinnvolles macht/machen kann, sollte man sie auch nicht behandeln.

Wenn man den Namen angepasst hat, dann gibt das aber immer noch nicht die von Dir angegebene Fehlermeldung, sondern einen `TypeError`. Du definierst ja IP und Port als Konstanten. Möchtest Du die nicht vielleicht auch irgendwo verwenden!?

Was gibt die `recv()` von Sockets denn Deiner Meinung nach zurück? Beschreib mal den Wert und dessen Typ(en) in Worten. Wo steht das in der Dokumentation? In der Zeile bekämst Du nämlich einen `TypeError` wenn der Code bis dahin käme.

Du solltest Dir zudem klar machen das TCP ein Datenstrom ist und `recv()` zwischen einem Byte und der dort angegebenen Anzahl liefert *und* das völlig unabhängig von der Anzahl der auf der anderen Seite gesendeten Bytes ist. Wenn die andere Seite 10 Bytes sendet, kann es trotzdem sein das `recv()` nur das erste Byte davon liefert. Man muss das so lange aufrufen bis man tatsächlich alle Daten zusammen hat, die man dann verarbeiten möchte.

Zwischen Funktion und öffnender Klammer für die Argumente gehört kein Leerzeichen.

Um das schliessen von Socket-Objekten zu garantieren, bietet sich die ``with``-Anweisung an.

Der Kommentar bei der PORT-Konstante ist merkwürdig. Läuft denn ein Programm das auf diesem Port auf Verbindungen wartet auf dem Rechner mit der `IP`? Was ist das für ein Programm? Was sendet das an einen Client der sich gerade verbunden hat?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Armend
User
Beiträge: 22
Registriert: Mittwoch 11. April 2018, 11:59

@__blackjack__: Doch das war tatsächlich die Fehlermeldung. Ich habe mich oben lediglich vertippt. Statt socket.connect() muss es socket_handler.connect() heißen.

Den Code, den ich oben aufgeschrieben habe, bitte nur als Beispiel betrachten.
Sockets habe ich bereits des öfteren verwendet, und auch erfolgreich. TCP und UDP. Der Unterschied ist aber der, dass ich immer beide Seiten (Server und Client) programmiert habe. Dazu findet man auch sehr vieles im Internet -> nichts neues.

Wie mache ich es aber, wenn ich die Daten vom Ethernet-Anschluss in Python mittels Sockets lesen will. Hat jeder Ethernet-Anschluss bereits ein Socket? Handelt es sich hierbei um ein Server oder Client?

Das Ganze sollte ungefähr so aussehen:
Steuergerät (Ethernet-Anschluss) ------------ (Ethernet-Anschluss) Rechner ---------- Python(Client? oder Server?)
Der Ethernet-Anschluss sollte über IPv4 und TCP erreichbar sein.
Benutzeravatar
__blackjack__
User
Beiträge: 13073
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Armend: Das mag die tatsächliche Fehlermeldung gewesen sein, aber dann war es halt nicht der gezeigte Code. Es macht keinen Sinn Fehlermeldungen und Code zu zeigen die gar nicht zusammengehören. Und auch ein Beispiel macht keinen Sinn wenn es nicht tatsächlich der Code ist, den Du auch laufen lässt. Wie soll man den sonst sagen können wodurch der Fehler zu einem Code den man nicht kennt, zustande kommt?

Vom Ethernet-Anschluss kannst/willst Du keine Daten lesen, denn der spricht Ethernet und nicht TCP oder UDP. Das dürfte aber auch eine Ebene sein, die Dich gar nicht interessiert. Ethernet-Anschlüsse haben kein Socket im Sinne vom `socket`-Modul und ein Ethernet-Anschluss ist auch weder Server noch Client. Du musst herausfinden was Dein Steuergerät für eine API/Schnittstelle hat. Also ob da ein Server drauf läuft, auf welchem Port der auf Verbindungen wartet wenn es TCP ist, oder über welchen Port er UDP-Pakete entgegennimmt, oder ob er da was ganz anderes macht. Und dann musst Du herausfinden welches Protokoll er über den Transportweg spricht, den er zur Verfügung stellt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Armend
User
Beiträge: 22
Registriert: Mittwoch 11. April 2018, 11:59

@__blackjack__: Ok passt soweit. Danke.
Ich bin an der Sache dran.
Ich denke, es müsste sich um ein standardisierten Prozess handeln. Diagnose sollte bei allen Steuergeräten gleich sein. Müsste sicherlich in der ISO definiert sein. Das habe ich jetzt mal so angenommen.
Hatte gehofft jemand hat das bereits gemacht und kann mich schon mal in die richtige Richtung leiten.

Ich muss mir das genauer anschauen.
Antworten