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?
Problemchen mit Pybluez?
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:
Noch nicht optimal, aber ein erster Ansatz. Hoffe ich konnte ein wenig helfen
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
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
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
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
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.
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 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?
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)
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 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?
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.
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
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
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
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.