Problemchen mit Pybluez?

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
Lonestar
User
Beiträge: 147
Registriert: Samstag 9. August 2008, 08:31

Hi,
ich bin mir nicht ganz sicher ob ich überhaupt ein Problem mit Pybluez habe oder ob das Problem eventuell auf der anderen Seite der Kommunikation liegt. Bei meinem bisschen googeln bin ich nicht wirklich weiter gekommen... also frage ich einfach mal hier in die Runde.

Ich habe eine Bluetoothverbindung mit einem Client aufgebaut. Als Beispiel habe ich mir das Beispiel hier rausgesucht. Die Kommunikation läuft eigentlich gut. Nur bekomme ich manchmal ziemlich lange Nachrichten vom Client geschickt. Der Aufruf 'data = client_sock.recv(1024)' gibt mir immer schön einen String mit den empfangenen Daten. Wird der vom Client gesendete string alerdings länger als 256 Zeichen bekomme ich den gesendeten String in maximal 256 Zeichen langen Teilstücken ausgegeben.
Mir ist schon klar das ich der Methode 'recv()' die maximale Datenmenge als Parameter übergebe. Reduziere ich den übergeben Wert bekomme ich auch kürzere strings. Allerding ist es mir noch nicht gelungen längere Zeichenketten zu empfangen. In der Doku zu Pybluez habe ich auch keine wirkliche Hilfe gefunden. Hat jemand vielleicht Erfahrungen und kann mir auf die Sprünge helfen?
Benutzeravatar
br3z3l
User
Beiträge: 10
Registriert: Mittwoch 30. Januar 2008, 21:31
Kontaktdaten:

In dem Beispiel wird recv() ja nur einmal aufgerufen, es können also nicht mehr als 1024 Bytes (also deine 256 Zeichen) gelesen werden. Du musst deshalb recv() in einer Schleife aufrufen solange Daten zum empfangen vorhanden sind.

Könnte in etwa so aussehen:

Code: Alles auswählen

data = received = client_sock.recv(1024)
while not len(received) < 1024:
    received = client_sock.recv(1024)
    data += received

print "received [%s]" % data
Noch nicht optimal, aber ein erster Ansatz. Hoffe ich konnte ein wenig helfen
Lonestar
User
Beiträge: 147
Registriert: Samstag 9. August 2008, 08:31

naja, ich hab schon eine Schleife laufen die Daten liest - es kommen auch alle Daten an, halt nur nicht in einem String - so wie ich sie eigentlich gesendet bekomme. An eine ähnliche Variante wie deine habe ich auch schon gedacht. Da ich aber vorher nie weiß wie lang der gesendete String vom Client ist muss ich den Client noch dazu bringen mir das vorher anzugeben oder halt das Ende eines Strings extra kennzeichnen. Das würde relativ aufwendig werden.
Mir geht es eher darum den Buffer zu erhöhen den ich der Methode recv() als Parameter übergebe. Wenn ich ihn runtersetze bekomme ich kürzere Teilstrings. Nur scheint es ein Maximum zu geben - ich bekomme maximal 256 Zeichen pro String.

Gibt es wirklich so ein Maximum für den Buffer? Oder ist das Quatsch mein Programm läuft völlig richtig und mein Client ist beim Senden von langen Strings vielleicht eingeschränkt und verursacht das Problem? Leider habe ich keine Möglichkeit das zu überprüfen da ich lediglich 2 Bluetooth Geräte habe auf die ich momentan zugreifen kann. Davon kann ich auch lediglich eines mit Python und pybluez laufen lassen so das ich einfach nicht mehr testen kann....
vielleicht hat ja jemand auf nem Samstag Nachmittag nichts besseres zu tun und könnte das zu Hause mal auf 2 Rechnern mit pybluez für nen wildfremden testen? Hier noch mal der Link zu 2 Scripten die als Server und Client reichen würden. Pybluez gibt es hier. Vielleicht kann man damit schon einmal eine Fehlerquelle eliminieren.
Oder kann mir jemand zu einem evtl. besserem Modul für Bluetooth raten? Ich bin da erst mal für jede Art von Hilfe offen :roll:
Benutzeravatar
br3z3l
User
Beiträge: 10
Registriert: Mittwoch 30. Januar 2008, 21:31
Kontaktdaten:

Dann ist es sicherlich hilfreich wenn du deinen bisherigen Code postest und dazu noch was du empfängst (plus: Wenn bekannt was von der anderen Seite gesendet wird). Deine Kommunikation, erfolgt die mit einem bestimten Gerät oder einem x-beliebigen Bluetooth Gerät welches RFCOMM unterstützt? Wird ein bestimmtes Protokoll verwendet? etc. etc :D
Lonestar
User
Beiträge: 147
Registriert: Samstag 9. August 2008, 08:31

na jut,
da mein momentaner Server wohl als Code nicht wirklich hilfreich wäre habe ich den handler um alles gekürzt was nichts mit der eigentlichen Verbindung zu tun hat. Die Konsolenausgaben die das nötigste Mitteilen hab ich auch mal wieder reingeschmissen und das Modul bei mir getestet. Auf meinem System (WinXP Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) mit pybluez) läuft der Code und nimmt auch Über BT Verbindungen entgegen.

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-


import bluetooth 
import threading
import Queue
import time

class BTServer(threading.Thread):

    def __init__(self, QueueIn, QueueOut):

        threading.Thread.__init__(self)
        
        #Warteschlangen für den Server
        self.QueueIn = QueueIn
        self.QueueOut = QueueOut
        
        #initiiern auf Port 0 -> freier Port wird zugewiesen
        self.Port = 0
        
        #bei schliessen des Main-Threads auch Server beenden
        self.setDaemon(True)

        self.createServer()
        
    def createServer(self):
        """
        BT-Server auf dynamischen PORT starten
        """
        self.server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
        self.server_sock.bind(("",self.Port))
        bluetooth.advertise_service( self.server_sock, "P900Remote",
                                     service_classes = [ bluetooth.SERIAL_PORT_CLASS ],
                                     profiles = [  bluetooth.SERIAL_PORT_PROFILE ] )
        self.server_sock.listen(1)
        print "BTServer erstellt auf Port", self.server_sock.getsockname()[1]
        
    def run(self):
        """
        Verbindungen Annehmen und an Handler weitergeben
        """
        while True: 
            self.client_sock, self.client_info = self.server_sock.accept()
            print "Accepted connection from ", self.client_info
            self.handle()
            
    def handle(self):
        
        StreamOffen = True
        while StreamOffen:
            
            #TODO: Maximale länge passt irgendwie nicht
            data = self.client_sock.recv(1024)
            if data == "":
                StreamOffen = False
                
            else:
                print "debug BT-Handler: Nachricht: ", data
                
        self.client_sock.close()  
        print"Verbindung  mit ", self.client_info, "beendet" 
          

if __name__ == '__main__':
    q1 = Queue.Queue
    q2 = Queue.Empty
    
    server = BTServer(q1, q2)
    
    server.start()
    while True:
        time.sleep(1)
Wie man sicher sieht ist das immer noch mehr oder weniger eine Kopie von dem oben geposteten Beispielen. Lediglich der Port wird dynamisch vergeben. Als Protokoll sollte eigentlich RFCOMM genommen werden wenn ich das richtig verstanden habe.
Die Daten die der Server empfängt sehen momentan so aus:

1342177507||2008-09-06 10:00:00||-1879047971||2008-09-10 07:00:00||

das ist immer nur eine ID mit einem Datum dahinter. Allerdings halt über 500 Zeichen lang. Die gesendeten Daten sind soweit ich das überschauen kann exakt die gleichen - das wird halt unübersichtlich ohne copy/paste :roll: Jedenfalls gibt es keine Sonder-/ oder Steuerzeichen.
Als Gegenstelle habe ich im Moment ein Sony Ericsson P900 das soweit ich weiss auch RFCOMM unterstützt. Ich habe noch keine anderen Angaben dazu gefunen und immerhin kann ich eine funktionierende Verbindung aufbauen.
Fehlen sonst noch irgendwelche Angaben?
BlackJack

Scheint alles in Ordnung zu sein. Du wirst damit leben müssen, dass die Daten zerstückelt werden, das ist ganz normal. Die Grösse der Stücke kann viele Ursachen haben -- Sendepuffer, Empfangspuffer, Paketgrössen bei Protokollen, die zur Datenübertragung dienen usw.
Lonestar
User
Beiträge: 147
Registriert: Samstag 9. August 2008, 08:31

Tja, dann werde ich den Client wohl überreden müssen mir das Ende eines übertragenen Strings zu kennzeichnen und so lange die ankommenden Daten zu einem großen String zusammenführen... das riecht nach ein wenig Arbeit die ich mir gerne erspart hätte :roll:

Mit solchen Problemen hätte ich eigentlich nicht gerechnet, da ich die selben Daten auch über TCP/IP versenden und empfangen kann. Dabei kann ich sogar eine Serielle Schnittstelle über BT zu meinem PC aufbauen und darüber die Daten senden. Da hatte ich überhaupt keine Probleme... und hab mal ganz blauäugig gedacht das Bluetooth prinzipiell kein Problem darstellen sollte.
Falls trotzdem noch jemand Ideen oder Informationene hätte - nur keine Hemmungen :wink:
BlackJack

Vorsicht! Bei TCP musst Du grundsätzlich auch damit rechnen, dass Daten die mit einem Aufruf gesendet wurden, auf der anderen Seite mit mehreren Leseaufrufen empfangen werden müssen! Wenn Du das nicht tust, hast Du eine kleine Zeitbombe, die nur darauf wartet irgendwann einmal zuzuschlagen.
Antworten