connect()上的蓝牙winsock错误10049

时间:2010-05-18 16:13:22

标签: c++ visual-c++ bluetooth winsock

我正在为visual-c ++开发一个用于客户端应用程序的DLL,以通过蓝牙将我的电脑连接到我的Android手机。我使用此功能在手机上查找我的蓝牙服务(请参阅注释代码!):

bool BlueRayXVR::findPairedService(GUID* guid, _SOCKET_ADDRESS* ret){
    this->checkStartup();

    HBLUETOOTH_DEVICE_FIND found_devices;

    BLUETOOTH_DEVICE_INFO device_info;
    device_info.dwSize = sizeof(device_info);

    BLUETOOTH_DEVICE_SEARCH_PARAMS search_criteria;
    search_criteria.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
    search_criteria.fReturnAuthenticated = TRUE;
    search_criteria.fReturnRemembered = FALSE;
    search_criteria.fReturnConnected = FALSE;
    search_criteria.fReturnUnknown = FALSE;
    search_criteria.fIssueInquiry = FALSE;
    search_criteria.cTimeoutMultiplier = 0;

    found_devices = BluetoothFindFirstDevice(&search_criteria, &device_info);

    if (found_devices == NULL)
    {
        _tprintf(TEXT("Error: \n%s\n"), getErrorMessage(WSAGetLastError(), error));
        return false;
    }

    WSAQUERYSET querySet;
    memset(&querySet, 0, sizeof(querySet));
    querySet.dwSize = sizeof(querySet);
    querySet.lpServiceClassId = guid;
    querySet.dwNameSpace = NS_BTH;

    SOCKADDR_BTH sab;
    memset (&sab, 0, sizeof(sab));
    sab.addressFamily  = AF_BTH;

    char addressAsString[1000];
    DWORD addressSize = sizeof(addressAsString);

    bool found = false;

    do
    {
        sab.btAddr = device_info.Address.ullLong;
        if (0 != WSAAddressToString((LPSOCKADDR)&sab, sizeof(sab), NULL, (LPWSTR)addressAsString, &addressSize)){
            _tprintf(TEXT("Error get the mac of the device %s\n.Going to the next device."), device_info.szName);
        }
        else{
            _tprintf(TEXT("Check on device %s%s for the service.\n"), device_info.szName, addressAsString);
            querySet.lpszContext =(LPWSTR) addressAsString;
            HANDLE service_lookup_handle;
            DWORD flags = LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_RETURN_BLOB;

            int result = WSALookupServiceBegin(&querySet, flags, &service_lookup_handle);

            if (0 == result)
            {
                BYTE buffer[2000];
                DWORD bufferLength = sizeof(buffer);
                WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
                if(0 == WSALookupServiceNext(service_lookup_handle, flags, &bufferLength, pResults))
                {
                    _tprintf(TEXT("Service : %s\n"), pResults->lpszServiceInstanceName);
                    _tprintf(TEXT("Comment : %s\n"), pResults->lpszComment);
                    *ret = pResults->lpcsaBuffer->RemoteAddr;
                    found = true;

                /*  this->sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);                      
                    if (0 == ::connect(sock, ret->lpSockaddr, ret->iSockaddrLength))
                    {
                        printf("connected");
                        //closesocket (*sock);
                        //return TRUE;
                    }
                    wprintf(L"errore %d: %s", WSAGetLastError(), this->getErrorMessage(WSAGetLastError(), this->error));
                    */
                }
                result = WSALookupServiceEnd(service_lookup_handle);
            }
            else
                _tprintf(TEXT("%s\nGoing to the next device..\n"), getErrorMessage(GetLastError(), error));
        }
    } while (BluetoothFindNextDevice(found_devices, &device_info) && !found);

    if(found_devices)
        BluetoothFindDeviceClose(found_devices);

    _tprintf(TEXT("No more device.\n"));
    return found;
}

这一个连接到手机:

bool BlueRayXVR::connect(_SOCKET_ADDRESS* host)
{
    this->sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); 
    if (this->sock == INVALID_SOCKET)
    {
        _tprintf(TEXT("Failed to get bluetooth socket! %s\n"), getErrorMessage(WSAGetLastError(), error));
        exit(1);
    }

    if (0 == ::connect(sock, host->lpSockaddr, host->iSockaddrLength))
    {
        printf("connected\n");
        return TRUE;
    }
    wprintf(L"errore %d: %s", WSAGetLastError(), this->getErrorMessage(WSAGetLastError(), this->error));
    return FALSE;
}

在我的测试控制台应用中,我这样做:

       _SOCKET_ADDRESS address;
    memset (&address, 0, sizeof(address));
    if(blue->findPairedService(&blue->getDefaultGUID4XVR(), &address)){
        printf("service founded..try to connect..\n");
        if(blue->connect(&address))
            blue->read();
    }

问题是,如果我运行我的代码,我总是得到错误10049。

奇怪的是,如果我取消注释findPairedService函数中的代码行,我就这样做了

       _SOCKET_ADDRESS address;
    memset (&address, 0, sizeof(address));
    if(blue->findPairedService(&blue->getDefaultGUID4XVR(), &address)){

它成功连接到手机....

怎么了?

谢谢!

1 个答案:

答案 0 :(得分:0)

根据文档,WSALookupServiceEnd“终止查询并清理上下文。”据推测,这包括删除/覆盖它返回的SOCKADDR结构中的值,以后稍后在connect调用中使用。所以只需创建自己的内存来存储结构,将返回的字节复制到其中,一切都应该没问题。

BTW您是否意识到Windows会自动执行任何必要的SDP查找;当connect()SOCKADDR_BTH.serviceClassId字段中获得服务类ID(UUID / Guid)时,它将执行SDP查找并找到RFCOMM端口号 - 您不再需要执行任何此类操作。 : - )