【熱門技術】Winsock 搜尋藍牙裝置

來源:互聯網
上載者:User

http://blog.csdn.net/JamesXing/article/details/1700338 這裡有各種藍芽相關的文章

我們如何檢索電腦上面的藍牙裝置呢,我們使用winsock搜尋藍牙裝置,請見程式碼分析

#include "stdafx.h"

#include <winsock2.h>
#include <ws2bth.h>

#pragma comment(lib,"ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
// 初始化winsock
WSADATA wsaData;
if( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
{
_tprintf(_T("WSAStartup failed with error code: %d\n"), WSAGetLastError());
return 1;
}

// 初始化藍芽枚舉結構
DWORD dwWsaqsLen = sizeof(WSAQUERYSET);
LPWSAQUERYSET lpWsaqs = (LPWSAQUERYSET)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwWsaqsLen);
lpWsaqs->dwSize = sizeof(WSAQUERYSET);
lpWsaqs->dwNameSpace = NS_BTH;

// 開始枚舉藍牙裝置
DWORD dwWsaqsFlags = LUP_CONTAINERS | LUP_FLUSHCACHE | LUP_RETURN_NAME | LUP_RETURN_ADDR;
HANDLE hService;

if(WSALookupServiceBegin(lpWsaqs, dwWsaqsFlags, &hService) != SOCKET_ERROR)
{
bool bFinished = false;
while(!bFinished)
{
if(WSALookupServiceNext(hService, dwWsaqsFlags, &dwWsaqsLen, lpWsaqs) == NO_ERROR)
{
SOCKADDR_BTH *saBth = (SOCKADDR_BTH*)lpWsaqs->lpcsaBuffer->RemoteAddr.lpSockaddr;
BTH_ADDR bthAddr = saBth->btAddr;

_tprintf(_T("\n發現藍牙裝置: \n"));
_tprintf(_T("------------------------\n"));
_tprintf(_T("NAP: 0x%04X SAP: 0x%08X 裝置名稱: %s\n"), GET_NAP(bthAddr), GET_SAP(bthAddr), lpWsaqs->lpszServiceInstanceName);
}
else
{
// 錯誤處理
switch(WSAGetLastError())
{
// 所給緩衝區過小,重新申請
case WSAEFAULT:
HeapFree(GetProcessHeap(), 0, lpWsaqs);
lpWsaqs = (LPWSAQUERYSET)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwWsaqsLen);
break;

// 沒有更多藍牙裝置了
case WSA_E_NO_MORE:
bFinished = true;
break;

default:
//bFinished = true;
break;
}
}
}
WSALookupServiceEnd( hService );
}

// 釋放資源
HeapFree(GetProcessHeap(), 0, lpWsaqs);
WSACleanup();

return 0;
}

使用WinSock串連到遠程藍牙裝置

你可以通過建立服務端和用戶端通訊端來串連兩個藍牙裝置。服務端通訊端必須設定為監聽傳入串連並接受用戶端通訊端;用戶端通訊端在發送串連請求之前必須要知道要串連到的裝置的地址。你也可以在Microsoft Windows CE上使用串口模擬方便地建立串連,詳情參見“利用虛擬串口串連到遠程裝置” 注意   為了使清晰起見,文中忽略了錯誤處理在建立串連前,你必須先獲得以下資訊:Ø            要查詢的遠程裝置的地址,BT_ADDR類型,定義在Ws2bth.h中:typedef ULONGLONG bt_addr, *pbt_addr, BT_ADDR, *PBT_ADDR; 注意   僅僅用戶端須要如此。Ø            一個GUID類型變數的服務識別符,或者RFCOMM通道(1到31)。 建立用戶端通訊端1.    提供Winsock的版本和實現細節的資料來初始化caller application。可以通過調用WSAStartup函數來獲得這個資料。WSADATA wsd;WSAStartup (MAKEWORD(1,0), &wsd);2.    調用socket函數來建立一個藍芽通訊端。SOCKET client_socket = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);socket函數的參數值將通訊端設定為藍芽服務。3.    通過設定SOCKADDR_BTH結構體來儲存用戶端要串連到的遠程裝置的資訊。a.    建立並初始化SOCKADDR_BTH變數。SOCKADDR_BTH sa;memset (&sa, 0, sizeof(sa));b.    將btAddr成員賦值為包含目標裝置地址的BT_ADDR變數。sa.btAddr = b; //b is a  BT_ADDR variable你的程式可以接受字串類型的裝置地址,但必須將其轉換並儲存為一個BT_ADDR類型變數。c.    如果服務識別符有效,則將serviceClassId成員設定為基於RFCOMM的服務的GUID。這種情況下,用戶端執行SDP查詢然後使用得到的伺服器通道。或者如果你要使用硬式編碼通道編號,將port成員變數設定為伺服器通道編號。sa.port = channel & 0xff;4.    調用connect函數來串連到藍芽通訊端。if (connect (client_socket, (SOCKADDR *)&sa, sizeof(sa))){ //Perform error handling. closesocket (client_socket); return 0;}傳遞第3步中設定好的SOCKADDR_BTH來指定目標裝置的屬性。串連建立後,你可以通過發送和接收資料來和目標裝置通訊。5.    要關閉與目標裝置的串連調用closesocket函數關閉藍芽通訊端,並且確保使用CloseHandle函數釋放通訊端。closesocket(client_socket);CloseHandle ((LPVOID)client_socket);6.    要結束對Winsock服務的使用,調用WSACleanup函數。在程式中對每個成功調用的WSAStartup都必須對應地調用WSACleanup。 To create a server socket1.      提供Winsock的版本和實現細節的資料來初始化caller application。可以通過調用WSAStartup函數來獲得這個資料。WSADATA wsd;WSAStartup (MAKEWORD(1,0), &wsd);2.      調用socket函數來建立一個藍芽通訊端。SOCKET server_socket = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);socket函數的參數值將通訊端設定為藍芽服務。3.      通過設定SOCKADDR_BTH結構體來儲存伺服器裝置的資訊。SOCKADDR_BTH sa;memset (&sa, 0, sizeof(sa));sa.addressFamily = AF_BT;sa.port = channel & 0xff; 注意   為了避免衝突,在選擇伺服器通道時建議將channel設定為0,這樣RFCOMM將自動使用下一個有效通道。結構體中的資訊用來將通訊端綁定到伺服器裝置的本地地址上。4.      調用bind函數綁定第二步中建立的server_socket,傳入第三步中建立的sa的引用指定裝置資訊。if (bind (server_socket, (SOCKADDR *)&sa, sizeof(sa))){ ... //Perform error handling closesocket (server_socket); return 0;}5.      用listen函數來監聽用戶端藍牙裝置發送的串連請求。if (listen (server_socket, 5)){ ... //Perform error handling closesocket (server_socket); return 0;}6.      用accept函數來接受傳入的串連請求。SOCKADDR_BTH sa2;int size = sizeof(sa2);SOCKET s2 = accept (server_socket, (SOCKADDR *)&sa2, &size);調用accept將返回SCOKADDR_BTH類型的用戶端地址。7.      調用closecocket函數來關閉通訊端。closesocket(server_socket);

要結束對Winsock服務的使用,調用WSACleanup函數。在程式中對每個成功調用的WSAStartup都必須對應地調用WSACleanup。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.