连接()时蓝牙winsock错误10049
我正在使用 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)){
成功连接到手机......
出了什么问题?
谢谢!
I'm developing a dll in visual-c++ for client side application to connect my pc to my android phone via bluetooth. I use this function to find my bluetooth service on the phone(see commented code!):
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;
}
And this one to connect to the phone:
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;
}
In my test console app i do:
_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();
}
The problem is that if i run my code i always get error 10049.
the strange thing is that if i uncomment the lines of code in findPairedService function and i just do
_SOCKET_ADDRESS address;
memset (&address, 0, sizeof(address));
if(blue->findPairedService(&blue->getDefaultGUID4XVR(), &address)){
it succesfully connect to the phone....
what's wrong??
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据文档,
WSALookupServiceEnd
“终止查询并清理上下文。”据推测,这包括删除/覆盖它返回的 SOCKADDR 结构中的值,稍后您将在 connect 调用中使用这些值。因此,只需创建您自己的内存位来存储结构,将返回的字节复制到其中,一切都应该没问题。顺便说一句,您是否意识到 Windows 会自动执行任何必要的 SDP 查找?当在
SOCKADDR_BTH.serviceClassId
字段中为connect()
提供服务类 Id (UUID/Guid) 时,它将执行 SDP 查找并找到 RFCOMM 端口号 - 并且你不再需要做任何这些事情。 :-)According to the docs,
WSALookupServiceEnd
"terminates the query and cleans up the context." Presumably that includes deleting/overwriting the values in the SOCKADDR struct that it returns, that you later use in the connect call. So just create your own bit of memory to store the struct, copy the returned bytes into it, and all should be fine.BTW do you realise that doing Windows will automatically do any necessary SDP lookup; when
connect()
is given a Service Class Id (UUID/Guid) in theSOCKADDR_BTH.serviceClassId
field it will do the SDP lookup and find the RFCOMM port number -- and you no longer need to do any of that stuff. :-)