Vorgehensweise bei sockets?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

Hi,
ist es sinniger den socket über die gesamte laufzeit des Programms offen(connect()) zu lassen und erst
am Ende zu schliessen oder sollte man den socket nach jeder Datenübertragung schliessen(close()) und bei Bedarf wieder neu öffnen/ connecten?

MfG Friedduck
BlackJack

@friedduck: Das kann man so pauschal nicht beantworten.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

ok @ BlackJack.

Dann frage ich anders: Wenn über den socket nur abundzu was verschickt wird und nichts empfangen, dann denke ich, wird es doch sauberer sein den socket
zu schliessen und bei bedarf wieder zu connecten um ressources zu sparen?
Wobei wenn ich kurzfristig wieder was zum Verschicken habe, könnte es nach hinten losgehen, die sockets brauchen ja nen Augenblick um sauber zu beenden bzw. bis das
System sie wieder rausrückt...
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@friedduck: Du solltest auf jeden Fall berücksichtigen, dass es zu Verbindungsabbrüchen kommen kann, egal, ob der Socket nur kurz oder für lange Zeit offen ist.
Wenn Du keinen Server planst, auf den gleichzeitig tausende Clients zugreifen, sollten Ressourcen eine sehr untergeordnete Rolle bei Deinen Überlegungen spielen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Ob du Sockets offen halten solltest oder nicht ist mit den Informationen gar nicht zu beantworten. Der Resourcenverbrauch ist aber erstmal völlig egal, selbst wenn er ein Problem werden sollte, ist schliesslich gar nicht klar ob deine Anwendung dieses Problem überhaupt lösen kann oder ob die Lösung für ein solches Problem darin besteht mehr Hardware zu verwenden.

Wenn du wirklich eine brauchbare Antwort haben willst müsstest du erstmal sagen was du überhaupt mit dem Socket machst bzw. was für ein Protokoll du verwendest. "Datenübertragung" sagt nämlich absolut gar nichts aus.
Dami123
User
Beiträge: 225
Registriert: Samstag 23. Februar 2013, 13:01

Wenn der Abstand zwischen den Sendungen variabel ist und es sich ab einer bestimmten Zeit nicht lohnen würde den socket offen zu lassen, kannst du "socket.timeout()" verwenden.
Bis die geschlossene Verbindung wieder verwendbar ist, braucht es ja eine gewisse Zeit. Da kannst du, wenn die genaue Zeit bekannt ist "time.sleep()", oder eben eine Endlos-Schleife verwenden bis die neue Datei gesendet wurde.
Eine Verbindung über einen neuen Port wäre auch eine Möglichkeit, wenn das gewünscht ist.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

danke an alle für die Antworten!

Was ich vorhabe ist eigentlich ganz simpel, es werden in unregelmässigen Abständen Berichte erzeugt, dich ich dann über den Port 9100 zu einem Drucker
durchschieben muss. Die Datenmenge ist überschauber, also im schnitt ca. 7 MB kann aber bei grossen Berichten an die 200MB hochgehen.
@friedduck: Du solltest auf jeden Fall berücksichtigen, dass es zu Verbindungsabbrüchen kommen kann, egal, ob der Socket nur kurz oder für lange Zeit offen ist.
Wenn Du keinen Server planst, auf den gleichzeitig tausende Clients zugreifen, sollten Ressourcen eine sehr untergeordnete Rolle bei Deinen Überlegungen spielen.
Das mit den Abbrüchen habe ich absolut nicht berücksichtigt, danke für den Hinweis, hilft mir enorm bei den weiteren überlegungen.
Wenn du wirklich eine brauchbare Antwort haben willst müsstest du erstmal sagen was du überhaupt mit dem Socket machst bzw. was für ein Protokoll du verwendest. "Datenübertragung" sagt nämlich absolut gar nichts aus.
Wahrscheinlich habe ich mich noch nicht tief genug in die Materie eingelesen, aber wenn ich einen socket mit AF_INET erzeuge, dann wird doch das TCP Protokoll verwendet, oder irre ich?
BlackJack

@friedduck: Ich denke es war die Frage gemeint was für ein Protokoll dann über TCP geht. Denn wenn die Verbindung dauerhaft besteht, muss man ja irgendwie die einzelnen Nachrichten/Dateien voneinander trennen können.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

@friedduck: Ich denke es war die Frage gemeint was für ein Protokoll dann über TCP geht. Denn wenn die Verbindung dauerhaft besteht, muss man ja irgendwie die einzelnen Nachrichten/Dateien voneinander trennen können.
achso, ok. Um ehrlich zu sein, weiß ich es nicht genau, wahrscheinlich gar keins. Ich schiebe die Datei mit sendall() einfach rüber...
Nicht die feine Art, oder?

Was habe ich denn an auswahl bei Protokollen, irgendein Infolink?
BlackJack

@friedduck: TCP ist ein Datenstrom. Wenn Du zwei oder mehr Dateien über die gleiche Verbindung überträgst, dann musst Du dem Empfänger ja irgendwie klar machen wo die Daten von einer Datei enden und die von der nächsten anfangen.

Auch wenn es funktionieren sollte, würde ich auch nicht empfehlen mehrere Megabyte, geschweige denn hunderte davon, mit einem einzigen `sendall()` zu versenden.

Keine Ahnung ob es ein passendes allgemeines Protokoll dafür gibt. Ich denke nicht. Das würde man sich dann wohl selber stricken. Vielleicht ein „streambares” Archiv-Format wie TAR verwenden. Allerdings denke ich bei diesem Szenario würde man einfach neue Verbindungen aufbauen, ausser es kommt regelmässig vor, das viele kleine Dateien schnell hintereinander versendet werden, dann würde sich der TCP-Verbindungsauf- und -abbau wahrscheinlich bemerkbar machen.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

in der Datei ist alles schon drin, die pcl Codes für die Fach ansteuerung u.s.w und natürlich die zu druckende Information. sprich es ist ein feriges Paket welches nur noch an den Drucker übergeben werden muss.
BlackJack

@friedduck: Was in der Datei ist, ist so ziemlich egal, ausser Du kannst am Inhalt festmachen wann sie zuende ist, um sie von der nächsten sauber trennen zu können. TCP ist ein Datenstrom, das kennt kein „Pakete”. Wenn Du also mehrere „Pakete” über die Leitung schickst, dann musst Du die irgendwie unterscheiden können.

Wenn es um's Drucken geht, warum schreibst Du da überhaupt etwas eigenes? Da gibt es doch schon verschiedene fertige Server.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

BlackJack hat geschrieben:@friedduck: Was in der Datei ist, ist so ziemlich egal, ausser Du kannst am Inhalt festmachen wann sie zuende ist, um sie von der nächsten sauber trennen zu können. TCP ist ein Datenstrom, das kennt kein „Pakete”. Wenn Du also mehrere „Pakete” über die Leitung schickst, dann musst Du die irgendwie unterscheiden können.

Wenn es um's Drucken geht, warum schreibst Du da überhaupt etwas eigenes? Da gibt es doch schon verschiedene fertige Server.
Hallo Blackjack, meinst du win32print? Oder gibt es noch was anderes?
BlackJack

@friedduck: Ich dachte an SMB oder IPP. Beides recht verbreitet und sowohl unter Windows als auch unter Linux möglich.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

SMB wird wohl eher zum scannen benuzt (ich zumindest habs noch nie in der Praxis gesehen), IPP wäre eine Idee, ist aber imho nicht so weit verbreitet wie die Druckübermittlung über TCP. Was auch noch erwähnenswert wäre ist LPR. Da muss ich mich noch einlesen.

Das schöne an der Druckerdatenübertragung über Port 9100 ist so eine Art fire&forget, das heisst wenn deine Druckdatei vernünftig generiert ist kümmert sich das Gerät um den rest. Was ich aber sicher feststellen müsste ist das die Datei vollständig rausgeschickt wird. Gibt es so eine art callback für send() oder sendall()?
BlackJack

@friedduck: Druckerfreigaben per SMB habe ich in der Praxis schon gesehen. IPP ist doch auch über TCP. Und vor allem gibt es da auch die Gegenrichtung mit Statusinformationen.
lunar

@friedduck Bei synchronen TCP-Sockets ist garantiert, dass die Gegenseite nach dem Aufruf ".send()" oder ".sendall()" alle Da. Das ist gerade der Sinn und Zweck von TCP im Vergleich zu UDP. Bei fehlerhafändigen Übertragungen lösen TCP-Sockets Ausnahmen aus. Eine explizite Prüfung auf Erfolg ist also nicht notwendig.

TCP garantiert allerdings nicht, dass die Gegenstelle die Dakonnte. Der Abwesenheit eines Fehlers beim Aufruf von ".sendall()" bedeutet also mitnichten, dass die Datei auch wirklich gedruckt wurde. Wenn Du also wissen willst, ob die Datei tatsächlich gedruckt wurde, dann musst Du eigentlich IPP verwenden, weil das so ziemlich das einzige Protokoll ist, was umfangreiche Status-Informationen über den Druckvorgang übermittelt.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

danke für die rege beteiligung, nach intensieven Studium der Druckprotokolle finde ich LPR auch garnicht mal so schlecht, ipp werde ich mir mal ansehen. Bei LPR hat man auch eine Art feedback ob alles ok ist oder nicht, und das direkt vom Drucker. Allerding soll das protokoll sehr "ugly" sein, naja bin noch bei der RFC beschreibung bei.

Wie heissen denn die IPP umsetzungen / wrapper für Python, wenn es denn welche gibt?
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

friedduck hat geschrieben:Wie heissen denn die IPP umsetzungen / wrapper für Python, wenn es denn welche gibt?
Google liefert: https://pypi.python.org/pypi/pkipplib

Aufgrund der niedrigen Versionsnummer und dem Upload von 2009 (im Sinn von: dass seitdem nix gemacht wurde) müsste man aber mal sehen, wie brauchbar dieser Treffer ist.
friedduck
User
Beiträge: 76
Registriert: Montag 23. Juli 2012, 20:41

Hallo,

sodele, habe mich jetzt für LPR und RAW entschieden. Gibt es egentlich eine möglichkeit um festzustellen ob ein socket
noch verbunden ist oder nicht, wenn man die gegenstelle nicht abfragen kann, oder wird es mit timeout erledigt?
Antworten