Wissen wann Socket geschlossen um csv-Datei zu erstellen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

Hallo Leute,

ich habe eine Frage :?: :arrow: Bin momentan dabei eine App mit Java zu schreiben und diese gibt mir die Kontaktdaten des Nutzers wieder. Die Daten schicke ich dann per Socket und DynDNS an meinen Rechner. Dort wartet folgendes Python-Skript und hört auf Port 50001, das die Daten dann in irgendeiner Form empfangen soll (wie, habe ich noch nicht festgelegt).

Code: Alles auswählen

import time
from twisted.internet import protocol, reactor, endpoints
import time

class Contact(protocol.Protocol):
       
    def dataReceived(self, data):



class ContactFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return Contact()

endpoints.serverFromString(reactor, "tcp:50001").listen(ContactFactory())
reactor.run()
Wenn die App den Socket schließt (nachdem die Kontaktdaten gesendet wurde) möchte ich die Wertein in einer Libre Calc Datei verwalten, die dann in der ersten Spalte alle Namen und in der zweiten alle Telefonnummern hat. Das wollte ich mit Python in ähnlich Form wie in folgender Code tun:

Code: Alles auswählen

import csv
contacts = [[Hier werden Namen stehen],[Hier die Telefonnummern]]
item_length = len(contacts[0])

with open('Contacts.csv', 'wb') as test_file:
  file_writer = csv.writer(test_file)
  for i in range(item_length):
    file_writer.writerow([x[i] for x in contacts])
Nun meine Frage: Woher weiß mein Python-Skript, dass der Socket auf dem Smartphone geschlossen wurde und er damit anfangen kann die Werte in die csv-Datei zu speichern?

Danke für eure Antworten, falls ihr sonst noch Anmerkungen zu meinem Vorhaben habt, tut euch keinen Zwang an, ich beschäftige mich noch nicht sehr lange mit Python und bin über jeden Tipp dankbar. :D :idea:
BlackJack

@cailleachsiam: Sonstige Anmerkungen: Man sollte zusammengehörige Daten nicht in ”parallelen” Listen speichern. Kontakt und Telefonnummer(n) gehören zusammen in ein Element der Kontaktdatenliste.

Wie bist Du auf Twisted gekommen? Weil das so schön nach Java aussieht mit den ganzen Klassen, Factories, und den „unpythonischen” Namenskonventionen? ;-)
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

@BlackJack: Twisted kann man doch statt Threads nehmen, oder? Habe ähnlichen Code online gefunden. Ich bekomme über andere Ports noch weitere Informationen. Dann schreibe ich die Werte in Java am besten in ein mehrdimensionales Array, oder? Aber wie kann ich die, wenn ich sie geschickt bekomme verarbeiten? Wenn ich dann Wert array[1][1] geschickt bekomm, wo und wie specher ich den dann ab, oder gibt es eine Möglichkeit, diesen direkt in die csv zu schreiben? Wenn ich die Werte als [1][1] an die csv übergebe und dann [2][2] schick und verarbeite usw.. dann speichert es mir die Werte doch falsch in meine Calc-Datei später?
Danke dir!
BlackJack

@cailleachsiam: Nur für dieses Beispiel kam mir Twisted ein *wenig* überdimensioniert vor.

Wie Du die Werte in Java speicherst ist doch vollkommen egal, die Frage ist wie Du sie serialisierst und als Bytes über das Netz schickst. Was Du mit „Werte als [1][1]” oder „[2][2]” schicken meinst, verstehe ich nicht!? Du musst die Daten beim Client halt irgendwie als Folge von Bytes serialisieren die man dann auf Serverseite wieder sinnvoll in eine Struktur parsen kann. Oder auch nicht, denn man könnte auch direkt CSV senden und beim Client die ankommenden Bytes einfach in eine Datei schreiben. Ansonsten sollte man nicht lange über irgend ein eigenes Format nachdenken, sondern etwas nehmen was schon etabliert ist. JSON zum Beispiel. Oder CSV. :-)

Noch mal zurück zu der Frage woher man bei einem Twisted-Protokoll weiss wann die Gegenseite keine Daten mehr sendet weil sie die Verbindung geschlossen hat: Das beantworte ich mal nicht direkt, weil man die Antwort wirklich *sehr* einfach selber findet wenn man sich mal die Anfängertutorials oder die API-Dokumentation von Twisted durchliest. Twisted ist zu komplex als das es sinnvoll wäre sich seinen Code irgendwie aus Quelltextfragmenten aus dem Netz zusammen zu frickeln ohne zu verstehen wie das Rahmenwerk und die einzelnen Komponenten funktionieren und zusammenspielen.
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

Sorry, war so früh am Morgen :) Also, wenn ich nicht Twisted nehmen würde, was würdest du mir denn dann empfehlen?
Bin jetzt soweit, dass mir die Daten in dem Format ['Name','Numer'], die einzelnen Einträge mit \n getrennt in eine Textdatei geschrieben werden.
Und wann die Verbindung getrennt wird, sagt mir connectionLost, habe ich das richtig herausgefunden? Meine Idee ist, eben alles in die .txt zu schreiben und in die connectionLost dann von der .txt in eine cvs zu schreiben (darum schon so halbwegs in dem richtigen Format). Ich könnte ja die .txt Einträge jeweils am \n trennen und dann in die .cvs schreiben. Ist das zu umständlich? Gibt es eine schlankere Lösung dafür? Wär super wenn du mir noch einen Tipp gibst ;) Danke

Code: Alles auswählen

   def connectionLost(self, reason):
        print "lost"
	
       
   def dataReceived(self, data):
	print "write"
	with open("Contacts/Contacts.txt","a") as outfile:
           outfile.write(data)
BlackJack

@cailleachsiam: Ob Twisted oder nicht hängt vom Anwendungsfall ab. Ich fand es halt für das Beispiel zu übertrieben. Kommt halt drauf an was da noch alles dazu kommt.

Warum der Umweg über eine Textdatei? Und warum doch ein eigenes Format erfinden statt zum Beispiel JSON zu nehmen? Für JSON und CSV gibt es Module in der Standardbibliothek.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Protocol Buffers wären noch eine Option, um Objekte zu serialisieren. Damit muss man sich nicht mehr manuell um das Serialisieren kümmern - allerdings kommt natürlich der Overhead für das Erstellen der Protokoll-Beschreibung neu hinzu ;-)

Für so simple Objekte bietet sich JSON vermutlich schon an. Für Java fand ich früher mal XStream gut (allerdings in Sachen XML - soll jetzt aber auch JSON können) und in Python ist es ja recht einfach, sich eigene Encoder und Decoder für sein Objekt zu schreiben.

Für die Netzwerkkommunikation könntest Du auch eine AMQP-Lösung wie RabbitMQ ausprobieren.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@cailleachsiam: erst einmal möchte ich die Sinnhaftigkeit Deiner angedachten Lösung hinterfragen: Warum sollen die Daten erst in die Datei geschrieben werden, wenn die Verbindung beendet wird? Normalerweise arbeiten Client-Server-Lösungen nach dem Prinzip Client schickt eine Anfrage - Server beantwortet sie. Vorgang abgeschlossen. Ein Beenden kann ja viele Gründe haben, nur einer davon ist, dass der Client seine Arbeit getan hat, die anderen sind: der Client stürzt ab, die Netzwerkverbindung bricht zusammen, irgendeine Box zwischen Client und Server erreicht einen Timeout, ... es gibt sicher noch etliche weitere Gründe.
Deine bisherige Lösung sieht nicht danach aus, als ob sie mit mehr als einer Anfrage zurecht kommt. Client-Server-Geschichten sind aber normalerweise auf viele Clients, mindestens ein Server ausgelegt, weshalb auch Frameworks wie Twisted so viel Wert auf Parallelität legen.
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

@sirius3 Wirklich viel Sinn hat das nicht, ich weiß. Wie gesagt, ich habe noch nicht soo viel programmiert, deswegen war das so meine erste Idee. Es soll erstmal nur darum gehen, Werte von einem Smartphone an den Server zu schicken. Ich schaue mir jetzt mal JSON an. Wenn das noch alles recht neu für einen ist, nimmt man eben die Infos die man finden kann und hangelt sich an dem schon vorhandenen voran ;)
Antworten