在 BT 关闭并再次打开后重新连接蓝牙套接字(在 Python 中)

Have Bluetooth socket reconnect (in Python) after BT switched off and on again

我在 python (3.10) 程序中连接蓝牙设备是这样的:

import socket
serverMACAddress = '00:07:80:e0:a4:fc'
port = 1
size = 1024
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((serverMACAddress,port))

在主循环中我有这个:

try:
    while 1: #main loop
        data = s.recv(size)
        if data:
            data_received( data )
        else:
            try:
                s.???? 
            except: 
                print("no data") 
except: 
    print("Closing socket")
    s.close()

除非蓝牙设备关闭然后再次打开,否则一切正常。我正在尝试解决如何让蓝牙设备与循环内的 try 语句 (s.?????) 中的逻辑重新连接,但我无法提出解决方案。

我是 BT 和 Python 的初学者,但这应该很简单,对吧?我一定错过了一些非常明显的东西。有什么建议吗?

根据 ukBaz 的建议修改版本:

try:
    while 1: #main loop
        try:
            data = s.recv(size)
        except socket.error():
            connected = False
            s = socket.socket
            while not connected:
                #attempt to re-connect
                try:
                    s.connect((serverMACAddress,port))
                    connected = True
                except:
                    time.sleep(5)
        if data:
            data_received( data )
except: 
    print("Closing socket")
    s.close()

添加后clientSocket.send:

while True: #main loop
    # attempt to reconnect, otherwise sleep for 2 seconds
    if not connected:
        try:
            # configure socket and connect to server
            clientSocket = socket.socket(
                socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM
            )

            clientSocket.connect((serverMACAddress, port))
            connected = True
            print("Connection successful")
        except socket.error:
            print("No connection, retrying")
#            time.sleep(2)
    # attempt to send and receive, otherwise reset connection status
    else:
        data = clientSocket.recv(size)
        if data:
            data_received( data )
        # Use send to check if scale is connected
        try:
            clientSocket.send(b"x")
        except socket.error:
            print("connection lost... reconnecting")
            # set connection status
            connected = False

我 运行 以下连接到 Arduino 上的远程 HC-06 模块。我用 Python 3.10 (Windows) 和 Python 3.8 (Linux) 测试了下面的代码,它在两者上都按预期工作。

它有一个连续的 while 循环,如果它已连接则发送和接收数据。如果未连接,则它会尝试连接。它使用 except socket.error 来检测连接是否存在问题。

import socket
from time import sleep

host = "00:00:12:34:56:78"
port = 1
chunks = 1024

# keep track of connection status
connected = False

while True:
    # attempt to reconnect, otherwise sleep for 2 seconds
    if not connected:
        try:
            # configure socket and connect to server
            clientSocket = socket.socket(
                socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM
            )

            clientSocket.connect((host, port))
            connected = True
            print("Connection successful")
        except socket.error:
            print("No connection, retrying")
            sleep(2)
    # attempt to send and receive, otherwise reset connection status
    else:
        try:
            print("sending data...")
            clientSocket.send(b"Test")
            print("Reading data..")
            message = clientSocket.recv(chunks).decode("UTF-8")
            print("Recv'd", message)
        except socket.error:
            # set connection status
            connected = False
            print("connection lost... reconnecting")

如果套接字只是在读,那么需要设置一个超时时间以引发异常。超时值可能需要根据您的特定情况进行调整。例如:

import socket
import time

import select

serverMACAddress = "00:00:12:34:56:78"
port = 1
size = 1024

# keep track of connection status
connected = False


def data_received(info):
    print(info)


while True: #main loop
    # attempt to reconnect, otherwise sleep for 2 seconds
    if not connected:
        try:
            # configure socket and connect to server
            clientSocket = socket.socket(
                socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM
            )

            clientSocket.connect((serverMACAddress, port))
            clientSocket.settimeout(5.5)
            connected = True
            print("Connection successful")
        except socket.error:
            print("No connection, retrying")
            time.sleep(2)
    # attempt to send and receive, otherwise reset connection status
    else:
        try:
            data = clientSocket.recv(size)
            print("Reading data..")
            if data:
                data_received(data)
        # Assume connection lost if read timeout raised
        except socket.timeout:
            # set connection status
            connected = False
            print("connection lost... reconnecting")