windows下蓝牙虚拟串口通信

windows下可以通过RFCOMM虚拟的串口进行通信.
RFCOMM简介:
RFCOMM仿真RS232串口,该仿真过程包括非数据通路状态的传输。RFCOMM不限制人工速率或步长,如果通信链路两端的设备都是负责将数据转发到其他通信介质的第二类设备,或在两端RFCOMM设备接口上进行数据传输,实际数据吞吐一般将反映波特率的设置.RFCOMM支持两个设备之间的多串口仿真,也支持多个设备多串口的仿真.
winsock支持RFCOMM,其地址是SOCKADDR_BTH,地址族是AF_BTH.
1.首先把蓝牙名字转换成能链接的地址。

ULONG CBlueTooth::NameToBthAddr( const char *pszRemoteName, PSOCKADDR_BTH pRemoteBtAddr)
{
    int             iResult = CXN_SUCCESS;
    BOOL            bContinueLookup = FALSE, bRemoteDeviceFound = FALSE;
    ULONG           ulFlags = 0, ulPQSSize = sizeof(WSAQUERYSET);
    HANDLE          hLookup = NULL;
    PWSAQUERYSET    pWSAQuerySet = NULL;

    ZeroMemory(pRemoteBtAddr, sizeof(*pRemoteBtAddr));
    pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),
        HEAP_ZERO_MEMORY,
        ulPQSSize);
    if ( NULL == pWSAQuerySet ) 
    {
        iResult = STATUS_NO_MEMORY;
    }
    if ( CXN_SUCCESS == iResult)
    {
        for ( int iRetryCount = 0;!bRemoteDeviceFound && (iRetryCount < CXN_MAX_INQUIRY_RETRY);iRetryCount++ )
        {   
            ulFlags = LUP_CONTAINERS;               
            ulFlags |= LUP_RETURN_NAME;             
            ulFlags |= LUP_RETURN_ADDR;

            if ( 0 != iRetryCount )
            {                                       
                ulFlags |= LUP_FLUSHCACHE;                  
                Sleep(CXN_DELAY_NEXT_INQUIRY * 1000);
            }

            iResult = CXN_SUCCESS;
            hLookup = 0;
            bContinueLookup = FALSE;
            ZeroMemory(pWSAQuerySet, ulPQSSize);
            pWSAQuerySet->dwNameSpace = NS_BTH;
            pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);
            iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);

            if ( (NO_ERROR == iResult) && (NULL != hLookup) ) 
            {
                bContinueLookup = TRUE;
            } else if ( 0 < iRetryCount )
            {                   
                break;
            }

            while ( bContinueLookup )
            {                   
                if ( NO_ERROR == WSALookupServiceNext(hLookup,
                    ulFlags,
                    &ulPQSSize,
                    pWSAQuerySet) )
                {
                    if ( ( pWSAQuerySet->lpszServiceInstanceName != NULL ) &&
                        ( CXN_SUCCESS == stricmp(pWSAQuerySet->lpszServiceInstanceName, pszRemoteName) ) )
                    {                               
                        CopyMemory(pRemoteBtAddr,
                            (PSOCKADDR_BTH) pWSAQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr,
                            sizeof(*pRemoteBtAddr));
                        bRemoteDeviceFound = TRUE;
                        bContinueLookup = FALSE;
                    }
                } else
                {
                    iResult = WSAGetLastError();
                    if ( WSA_E_NO_MORE == iResult )
                    { 
                        bContinueLookup = FALSE;
                    }
                    else if ( WSAEFAULT == iResult )
                    {                           
                        HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
                        pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),
                            HEAP_ZERO_MEMORY,
                            ulPQSSize);
                        if ( NULL == pWSAQuerySet )
                        {                               
                            iResult = STATUS_NO_MEMORY;
                            bContinueLookup = FALSE;
                        }
                    }
                    else
                    {                       
                        bContinueLookup = FALSE;
                    }
                }
            }

            WSALookupServiceEnd(hLookup);
            if ( STATUS_NO_MEMORY == iResult )
            {
                break;
            }
        }

    }
    if ( NULL != pWSAQuerySet )
    {
        HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
        pWSAQuerySet = NULL;
    }
    if ( bRemoteDeviceFound )
    {
        iResult = CXN_SUCCESS;
    } else
    {
        iResult = CXN_ERROR;
    }

    return iResult;
}

2.建立链接

//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BTHPORT\Parameters\LocalServices\{00001101-0000-1000-8000-00805f9b34fb}
/*
CBlueTooth:是本模块的底层通讯的类,该类为ECU类提供服务,该类把ECU要发送的类容抽象成类,通过发送和接收缓冲,保存该流的内容,而不管实际的发送或
接收的数据的意义。
*/
DEFINE_GUID(g_guidServiceClass,0x00001101,0x0000,0x1000,0x80,0x00,0x00,0x80,0x5f,0x9b,0x34,0xfb);
//RemoteBthAddr,蓝牙设备的地址
    SOCKADDR_BTH  SockAddrBthServer= RemoteBthAddr;
    SockAddrBthServer.addressFamily = AF_BTH;
    SockAddrBthServer.serviceClassId = g_guidServiceClass;
    SockAddrBthServer.port = 0;
    if (INVALID_SOCKET != LocalSocket)
    {
        closesocket(LocalSocket);
    }
    LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if ( INVALID_SOCKET == LocalSocket )
    {
        return status;
    }
    //建立蓝牙连接
    if ( 0 == connect(LocalSocket,
        (struct sockaddr *) &SockAddrBthServer,
        sizeof(SOCKADDR_BTH)) ) 
    {
        status=true;
    }

3.发送数据

ResetEvent(hSendEvent);
    int sum=0;
    while (sum < PDU.size())
    {
        int iCount=send(LocalSocket,PDU.data()+sum,PDU.size()-sum,0);
        if (iCount == SOCKET_ERROR)
        {
            bConnect = false;
        }
        sum += iCount;
    }
4.接收数据
while(1)
        {
            char buffer[100]={0};
            int count=recv(LocalSocket,buffer,sizeof(buffer),0);
            if (count < 0)
            {               
                continue;               
            }
            CurSum +=count; 
            if (0 != count)
            {

                for (int i=0;i<count;i++)
                {
                    ReceiveBuffer.push_back(buffer[i]);
                }
                            }
            if(ReceiveBuffer.size() >= 6 && (DestSum == 8))
            {
                unsigned short int *p =(unsigned short int*)(ReceiveBuffer.data()+4);
                DestSum += *p;              
            }
            if (DestSum != 0 && CurSum >= DestSum)
            {
                break;
            }
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#中使用蓝牙虚拟串口,你需要使用System.IO.Ports命名空间中的SerialPort类。但是,与传统串口不同,蓝牙串口需要使用RFCOMM协议进行通信。 首先,你需要确保你的计算机上已经安装了蓝牙适配器,并且已经成功地与目标设备进行了配对。 接下来,你需要在你的C#项目中添加System.IO.Ports命名空间。然后,你可以使用以下代码来设置蓝牙串口: ```csharp SerialPort bluetoothPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One); bluetoothPort.PortName = "COM10"; // 更改为你的蓝牙串口的名称 bluetoothPort.BaudRate = 9600; // 更改为你的蓝牙串口的波特率 bluetoothPort.Parity = Parity.None; bluetoothPort.DataBits = 8; bluetoothPort.StopBits = StopBits.One; bluetoothPort.Handshake = Handshake.None; bluetoothPort.ReadTimeout = 500; bluetoothPort.WriteTimeout = 500; bluetoothPort.Open(); // 打开蓝牙串口 ``` 注意:在设置蓝牙串口之前,你需要找到你的蓝牙串口的名称。你可以在Windows设备管理器中找到它,或者在设备配对时记下它。 一旦你成功地打开了蓝牙串口,你就可以使用SerialPort类中的Read和Write方法来读取和写入数据。例如,以下代码将向蓝牙串口写入数据: ```csharp bluetoothPort.Write("Hello, Bluetooth!"); ``` 然后,你可以使用以下代码从蓝牙串口读取数据: ```csharp string message = bluetoothPort.ReadLine(); ``` 当你完成与蓝牙串口的通信后,记得关闭串口: ```csharp bluetoothPort.Close(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值