Python Kommunikation zwischen 2 PC's

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 26. März 2009, 14:19

@bcit6k: Windows oder Linux?
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Donnerstag 26. März 2009, 14:44

jetzt hab ich doch noch eine frage.

mir ist jetzt so weit klar das der server ,wenn der client connectedist ihm auch die ausgabe zusendet. aber bei mir wartet der server immer bis sich ein client verbindet, ich möchte das er einfach sendet ohne darauf zu warten das sich ein client connected, aber wie des weis ich nicht
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Donnerstag 26. März 2009, 14:45

windoof
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Donnerstag 26. März 2009, 15:14

An wen soll der Server was senden wenn kein Client verbunden ist? Das geht nicht, egal ob nun XML-RPC oder low level sockets.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
alpha
User
Beiträge: 195
Registriert: Freitag 23. Mai 2003, 23:24
Wohnort: Ulm

Donnerstag 26. März 2009, 15:24

Du hast jetzt wohl sowas:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)

und Dein Server kommt über das listen nicht hinaus. Da mußt die wohl
den Kommunikationsteil in einen eigenen Thread packen. Schau dir mal das
Modul "threading" an.

Gruß
alpha
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Donnerstag 26. März 2009, 15:37

ok, kannst du mir vieleicht kurz beschreiben wie das threating funktioniert? damit ich mal eine idee hab wie das ablaufen könnte

danke!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 26. März 2009, 15:51

bcit6k hat geschrieben:kannst du mir vieleicht kurz beschreiben wie das threating funktioniert?
Hallo bcit6k!

Ich kann dir ein Beispiel geben:
server.py:

Code: Alles auswählen

#!/usr/bin/env python
#coding: iso-8859-15
"""
XMLRPC-Server
"""

import socket
socket.setdefaulttimeout(3) # Timeout auf 3 sec. setzen
import time
import threading
import xmlrpclib 
from SimpleXMLRPCServer import SimpleXMLRPCServer
from Queue import Queue

MAX_QUEUE_ITEMS = 10


class LoggingXmlRpcServer(SimpleXMLRPCServer, threading.Thread):
    
    def __init__(self, *args, **kwargs):
        SimpleXMLRPCServer.__init__(self, *args, **kwargs)
        threading.Thread.__init__(self)
        self.register_function(self.get_loglist)
        self._stopped = threading.Event()
        self._queue = Queue(MAX_QUEUE_ITEMS)
    
    
    def get_loglist(self):
        loglist = []
        for i in xrange(MAX_QUEUE_ITEMS):
            if self._queue.empty():
                break
            else:
                loglist.append(self._queue.get())
        return loglist
    
    
    def log(self, message):
        if self._queue.full():
            # ältesten Eintrag verwerfen
            self._queue.get()
        self._queue.put(message)
    
    
    def run(self):
        # Info: Diese Methode läuft in einem eigenen Thread
        while not self._stopped.isSet():
            self.handle_request()
        print "Thread stopped"
    
    
    def stop(self):
        self._stopped.set()
        self.join() # warten, bis der Thread beendet wurde (ca. 3 sec)


def main():
    server = LoggingXmlRpcServer(("0.0.0.0", 50505), logRequests = False)
    print "Der XMLRPC-Server horcht auf http://localhost:50505."
    print "Er kann mit STRG+C beendet werden."
    
    server.start()
    try:
        # zum Testen
        for i in range(100):
            time.sleep(0.3)
            text = "Zeile %i" % i
            print text
            server.log(text)
    except KeyboardInterrupt:
        print "KeyboardInterrupt"
    finally:
        server.stop()


if __name__ == "__main__":
    main()
client.py:

Code: Alles auswählen

#!/usr/bin/env python
#coding: iso-8859-15
"""
XMLRPC-Client
"""

import socket
socket.setdefaulttimeout(3) # Timeout auf 3 sec. setzen
import xmlrpclib
import time


def main():
    server = xmlrpclib.ServerProxy("http://localhost:50505")
    while True:
        try:
            loglist = server.get_loglist()
            for item in loglist:
                print "Client: ", item
        except socket.error:
            break
        time.sleep(2)
    print "Client: Verbindung abgebrochen!"


if __name__ == "__main__":
    main()
mfg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 26. März 2009, 15:58, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Donnerstag 26. März 2009, 15:56

danke für das beispiel, ich schau mir das gleich mal genauer an, aber ich denk ich kann mri schon gut vorstellen wie das funktioniert!
alpha
User
Beiträge: 195
Registriert: Freitag 23. Mai 2003, 23:24
Wohnort: Ulm

Donnerstag 26. März 2009, 16:25

Von mir auch noch ein Beispiel aber gegen das von Gerold stinkt es ziemlich ab. Ist auch super quick´n´dirty gemacht und sollte nur als grober Ansatz verstanden werden.

:)

Server:

Code: Alles auswählen

# Echo server program
import socket
import threading
import time

class Connection(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.connected = 0
        
    def run(self):
        HOST = '10.101.41.8'     # Symbolic name meaning the local host
        PORT = 55000              # Arbitrary non-privileged port
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((HOST, PORT))
        s.listen(1)
        self.conn, addr = s.accept()
        print 'Connected by', addr, self.conn
        self.connected = 1

    def send(self, text):
        if self.connected == 1:
            self.conn.send(text)
   

connection = Connection()
connection.start()
i = 0
while 1:
    i = i + 1
    print "status" + str(i)
    connection.send("status" + str(i))
    time.sleep(1)
Client:

Code: Alles auswählen

# Echo client program
import socket
import time
import copy

HOST = '10.101.41.8'    # The remote host
PORT = 55000             # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

    
while 1:
    data = s.recv(1024)
    print 'Received', `data`
Gruß
alpha
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 26. März 2009, 16:28

alpha hat geschrieben:aber gegen das von Gerold stinkt es ziemlich ab.
Hallo alpha!

Nicht so bescheiden. Ich kenne mich dafür nicht mit Socket aus und bin froh, dass du dafür ein Beispiel gemacht hast.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Donnerstag 26. März 2009, 16:38

Hallo alpha,

das beispiel ist schon ziemlich das was ich versuche zu baun, danke für den beitrag das bringt mich ordentlichweiter!

;)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 26. März 2009, 16:41

Hallo!

Das Beste ist ja, dass ich persönlich dieses Problem komplett anders lösen würde.

Ich würde schlicht, in eine Textdatei loggen.
Vom Client aus, würde ich mich per SSH zum Servercomputer verbinden und die Ausgabe des Befehls "tail -F <Pfad zur Logdatei>" anzeigen lassen. Hat man auf dem Client kein SSH zur Verfügung, dann nimmt man Putty dafür.

Im Python-Programm muss man nur darauf achten, dass nach jedem Schreibzugriff, ein ``<file>.flush()`` ausgeführt wird.

Da das Python-Programm auf einem Windows-Computer ausgeführt wird, muss man zuerst noch Cygwin und OpenSSH installieren. Aber bei mir im Umkreis, gibt es sowiso keinen Windows-Computer ohne Cygwin. :-)

EDIT: Diese Lösung hat gleich mehrere Vorteile:
- Man braucht sich nicht für jedes Programm eine Remote-Logging-Lösung ausdenken. Man loggt einfach in Textdateien. Das Python-Modul "logging" stellt dafür weitreichende Möglichkeiten zur Verfügung.
- Kein Threading im Python-Programm. Das vereinfacht die Sache enorm.
- Mehrere Clients können gleichzeitig die Logdatei verfolgen.
- Diese Lösung ist besser in ein vorhandenes Überwachungssystem einbeziehbar.
- Ganz nebenbei, kann man den Windows-Computer per SSH fernwarten und hat Unix-Tools zur Verfügung, welche einem die Admin-Arbeit erleichtern.
- Da der SSH-Port sowiso meist offen ist, braucht man die Firewalleinstellungen nicht verändern.
- Die Übertragung des Logs passiert verschlüsselt und niemand kann sich einfach so, ohne Passwort oder Key am SSH-Server anmelden. --> Sicherheit
- ...

Wenn sich jemand für diese Lösung interessiert -- ich erkläre gerne, wie man Cygwin und OpenSSH installiert.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Donnerstag 26. März 2009, 16:50

danke für die idee, ich logge bereits meine events in einer datenbank mit. oder besser ich hab sie mitgeloggtt bis die tabelle 24 mio einträge hatte.
eigentlich will ich ja nur sehen was das skript macht :) danke für dein angebot
alpha
User
Beiträge: 195
Registriert: Freitag 23. Mai 2003, 23:24
Wohnort: Ulm

Donnerstag 26. März 2009, 17:26

Hehe.. Um zu sehen was mein Script macht würd ich unter Windows Remote Desktop oder VNC nehmen.
So ein Remotelogging ist interessant wenn dein Programm auf ner kleinen Steuerung mit Compactflashkarte läuft.. da ist dann nicht viel mit loggen (Platz und Schreibzyklen)
Ne Interessante Aufgabe ist es alle mal. Nur so lernt man dazu.

Viel Erfolg

@Gerold:
Hab mir gerade die Beschreibung von tail angesehen.. Toll was es alles gibt.. kann ich vielleicht mal brauchen. :)
Antworten