我已经使用基于RFCOMM和串行端口配置文件(SPP)的MS蓝牙插座在我的PC和蓝牙设备之间建立了连接。
连续接收数据没有问题。但是,如果想发送一个字节(作为命令),设备不会接收它。
以下是代码片段(省略了错误处理):SOCKET s = ::socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); //successful
...
SOCKADDR_BTH btSockAddr;
ZeroMemory(&btSockAddr, sizeof(SOCKADDR_BTH));
btSockAddr.addressFamily = AF_BTH;
btSockAddr.btAddr = DEVICE_ADDRESS;
btSockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID; //SerialPortServiceClass_UUID
btSockAddr.port = BT_PORT_ANY;
...
err = ::connect(s, reinterpret_cast<SOCKADDR*>(&btSockAddr), sizeof(SOCKADDR_BTH)); //successful
char cmd = 'm'; //switch mode
int sentSize = ::send(s, &cmd, 1, 0); //successful, sentSize = 1
...
for(;;)
{
char out;
int recvSize = ::recv(s, &out, 1, 0); //successful, receive byte by byte
...
}
虽然::send
返回成功,但设备的模式没有改变。因此,显然,给出的字节没有被传输,仍然驻留在发送缓冲区中(这是我的假设)。是否有一种方法来强制发送只有一个字节,即发送无缓冲?
我可以排除设备方面的错误。手动设置蓝牙链接(Windows通知栏/蓝牙/添加设备),并使用Putty建立串行连接,接收和发送都正常。
操作系统:Windows 7IDE: Visual Studio 2010
当您使用Putty与虚拟COM端口时,您是否在输入单个命令字符后单击返回?
我怀疑是这样,因此您需要在命令字节之后发送CR+LF。所以传递一个大小为3的缓冲区来发送(即{
好,试试第二个!: -)
这一行可能是问题所在:
btSockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID; //SerialPortServiceClass_UUID
为什么从SerialPortServiceClass_UUID更改?使用RFCOMM_PROTOCOL_UUID,告诉RFCOMM套接字连接到使用RFCOMM协议的SDP(服务数据库)中的任何服务。而应该是:
btSockAddr.serviceClassId = SerialPortServiceClass_UUID
(当然,如果设备在SD中只有一个RFCOMM服务,这实际上不会导致您所看到的问题)。