我有一个 C++ 脚本,我在树莓派上运行该脚本,以自动连接到尝试连接并接收固定大小 8 的数组的设备:
#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main() {
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
socklen_t opt = sizeof(rem_addr);
int server_sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
loc_addr.rc_family = AF_BLUETOOTH;
memset(&loc_addr.rc_bdaddr, 0, sizeof(loc_addr.rc_bdaddr));
loc_addr.rc_channel = (uint8_t) 1;
if (bind(server_sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
perror("Failed to bind Bluetooth socket");
return 1;
}
listen(server_sock, 1);
while (true) {
std::cout << "Waiting for connections..." << std::endl;
int client_sock = accept(server_sock, (struct sockaddr *)&rem_addr, &opt);
if (client_sock < 0) {
std::cerr << "Failed to accept connection" << std::endl;
continue;
}
std::cout << "Connection accepted" << std::endl;
while (true) {
float buffer[8];
int bytes_read = read(client_sock, buffer, sizeof(buffer));
if (bytes_read > 0) {
std::cout << "Received array of floats:" << std::endl;
for (int i = 0; i < 8; ++i) {
std::cout << buffer[i] << std::endl;
}
} else {
std::cout << "Connection closed or read error" << std::endl;
break;
}
}
close(client_sock);
}
close(server_sock);
return 0;
}
当我编译并运行它时,它会等待消息
$ ./client
Waiting for connections...
然后我在笔记本电脑上运行以下 python 脚本:
import struct
import bluetooth
class Driver():
def __init__(self):
self.serverMACAddress = 'DC:A6:32:99:B1:66' # mock mac address
self.port = 1
self.device_socket = None
def main(self):
print("connecting...")
self.connect()
def connect(self):
self.device_socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
self.device_socket.connect((self.serverMACAddress, self.port))
def send(self,message):
print("sending {}".format(message))
data = struct.pack('8f', *message)
self.sock.send(data)
self.sock.close()
if __name__ == "__main__":
d = Driver()
d.main()
d.send([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8])
但是,Python 脚本在 2 秒后生成以下错误:
> python .\remote_driver\driver.py
connecting...
Traceback (most recent call last):
File "C:\<Path>\remote_driver\driver.py", line 37, in <module>
d.main()
File "C:\<Path>\remote_driver\driver.py", line 21, in main
self.connect()
File "C:\<Path>\remote_driver\driver.py", line 25, in connect
self.device_socket.connect((self.serverMACAddress, self.port))
File "C:\Users\<User>\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\bluetooth\msbt.py", line 96, in connect
bt.connect (self._sockfd, addr, port)
OSError: A socket operation was attempted to an unreachable network.
在设置这两个脚本时是否有什么我没有考虑到导致此错误发生的原因?我已经使用
bluetoothctl
-> discoverable on
使我的 raspi 可发现,但这没有什么区别,在我的 Windows 11 笔记本电脑上,允许所有与规则不匹配的出站连接。
那些 C 函数一直很狡猾。这可以作为 Python 程序在两种设备上作为客户端或服务器运行。在 Pi 上,您可能首先需要“hciconfig hci0 piscan”。有关 Pi 上将连接到此 Python 代码的 C 代码,请参阅:
https://github.com/petzval/btferret
#!/usr/bin/python3
import socket
############ CLIENT #######################
def client(node):
node_address = "DC:A6:32:04:DB:56"
rfcomm_channel = 16
print("Trying to connect to " + node_address + " on channel " + str(rfcomm_channel) + "...")
try:
node.connect((node_address,rfcomm_channel))
except:
node.close()
print("Failed. On Linux, both devices must be visible:")
print(" hciconfig hci0 piscan")
print(" python3 bluetooth.py")
quit()
######### CONNECTED AS CLIENT ###########
node.settimeout(3.0)
print("Connected OK")
node.send("abcd".encode())
print("Disconnecting...")
return
################# SERVER ##########
def server(dd):
rfcomm_channel = 16 # change this if another program is using channel 16
try:
dd.bind(("00:00:00:00:00:00",rfcomm_channel))
except:
print("No Bluetooth, or channel " + str(rfcomm_channel) + " in use")
print("Turn Bluetooth off/on or edit code to use a different rfcomm_channel")
dd.close()
quit()
dd.listen()
print("Waiting for remote device to connect on RFCOMM channel " + str(rfcomm_channel))
dd.settimeout(3.0)
flag = 0
while flag == 0:
flag = 1
try:
(node,add) = dd.accept()
except TimeoutError:
flag = 0
except OSError:
flag = 0
except:
dd.close()
quit()
####### CONNECTED AS SERVER #########
node.settimeout(3.0)
print("Connected OK to " + str(add))
print("Waiting for data")
dat = node.recv(4)
print(dat)
print("Disconnecting...")
node.close()
return
# end server
########## START ##############
try:
fd = socket.socket(socket.AF_BLUETOOTH,socket.SOCK_STREAM,socket.BTPROTO_RFCOMM)
except:
print("No Bluetooth")
quit()
print("Input s or c for this device")
print(" s = Server")
print(" c = Client")
sorc = input("? ")
if sorc[0] == 's':
server(fd)
elif sorc[0] == 'c':
client(fd)
fd.close()
print("Exit")