头文件.h
#pragma once #ifndef NS_BTH #include "ws2bth.h" //如果没有定义NS_BTH宏,则将PSDK头文件包含进来 #endif // for WSALookupServiceBegin() WSALookupServiceNext etc. #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") #include <ws2bth.h> // for BluetoothFindFirstDevice() BluetoothFindNextDevice() etc. #include <bthsdpdef.h> #include <BluetoothAPIs.h> #pragma comment ( lib, "Irprops.lib") #ifndef BTH_ADDR typedef ULONGLONG BTH_ADDR; #endif #ifndef SAFE_DELETE #define SAFE_DELETE(pObj) {if(pObj) delete pObj; pObj = NULL;} #endif #ifndef SAFE_DELETERG #define SAFE_DELETERG(pObj) {if(pObj) delete [] pObj; pObj = NULL;} #endif #define RECEIVE_OVER_COMMAND 0x00001000 typedef struct _tag_BthDev_Info { BTH_ADDR btAddr; TCHAR szAddr[32]; TCHAR szName[128]; _tag_BthDev_Info() { memset(this, 0, sizeof(this)); } } BTHDEV_INFO; class CGGBlueTooth { public: CGGBlueTooth(); ~CGGBlueTooth(); BOOL StartSearchBthDev(IN DWORD dwControlFlags); BOOL GetNextBthDev( IN OUT BTHDEV_INFO *pcBthDevInfo, IN DWORD dwControlFlags = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE ); BOOL EndSearchBthDev(); //Socket Api BOOL Create(int af = AF_BTH, int type = SOCK_STREAM, int protocol = BTHPROTO_RFCOMM); BOOL Close(); //If no error occurs, this function returns zero. If an error occurs, it returns SOCKET_ERROR int Bind(BTH_ADDR sktAddr = 0, ULONG port = BT_PORT_ANY); int Listen(IN int backlog); int GetSockName(BTH_ADDR *psktAddr, ULONG *port); int SetBthService(TCHAR *lpServiceName); int Accept(CGGBlueTooth *pcBth); int Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond = -1); int Send(LPVOID lpData, int len, int flags = 0); int Recv(LPVOID lpData, int len, int flags = 0); int SendAll(LPVOID lpData, int len, int flags = 0); int RecvAll(LPVOID lpData, int len, int flags = 0); private: void HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac); private: HANDLE m_hLookup; SOCKET m_hSocket; SOCKADDR_BTH m_sktAddr; };
====================================================================================================================
源文件.cpp
#include "stdafx.h" #include "GGBlueTooth.h" //#include "tchar.h" CGGBlueTooth::CGGBlueTooth() : m_hLookup(NULL) , m_hSocket(NULL) { memset(&m_sktAddr, 0, sizeof(m_sktAddr)); } CGGBlueTooth::~CGGBlueTooth() { EndSearchBthDev(); Close(); } void CGGBlueTooth::HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac) { BYTE *pbAddr = (BYTE*)&dw64Addr; _stprintf( pstrMac, _T("%02X:%02X:%02X:%02X:%02X:%02X"), pbAddr[5], pbAddr[4], pbAddr[3], pbAddr[2], pbAddr[1], pbAddr[0] ); } BOOL CGGBlueTooth::StartSearchBthDev(IN DWORD dwControlFlags) { WSAQUERYSET wsaq; ZeroMemory(&wsaq, sizeof(wsaq)); wsaq.dwSize = sizeof(wsaq); wsaq.dwNameSpace = NS_BTH; wsaq.lpcsaBuffer = NULL; return WSALookupServiceBegin(&wsaq, dwControlFlags, &m_hLookup) == ERROR_SUCCESS ? TRUE : FALSE; } BOOL CGGBlueTooth::GetNextBthDev( IN OUT BTHDEV_INFO *pcBthDevInfo, IN DWORD dwControlFlags /* = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE*/ ) { if (!m_hLookup || !pcBthDevInfo) { return FALSE; } memset(pcBthDevInfo->szAddr, 0, sizeof(pcBthDevInfo->szAddr)); memset(pcBthDevInfo->szName, 0, sizeof(pcBthDevInfo->szName)); union { CHAR buf[5000]; double __unused; // ensure proper alignment }; LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET)buf; DWORD dwSize = sizeof(buf); int nResult; ZeroMemory(pwsaResults, sizeof(WSAQUERYSET)); pwsaResults->dwSize = sizeof(WSAQUERYSET); pwsaResults->dwNameSpace = NS_BTH; pwsaResults->lpBlob = NULL; nResult = WSALookupServiceNext(m_hLookup, dwControlFlags, &dwSize, pwsaResults); if (nResult == ERROR_SUCCESS) { pcBthDevInfo->btAddr = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr; BOOL bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName); if (bHaveName) { HexMac2String(pcBthDevInfo->btAddr, pcBthDevInfo->szAddr); _tcscpy(pcBthDevInfo->szName, pwsaResults->lpszServiceInstanceName); } return TRUE; } return FALSE; } BOOL CGGBlueTooth::EndSearchBthDev() { if (m_hLookup) { WSALookupServiceEnd(m_hLookup); m_hLookup = NULL; return TRUE; } return FALSE; } ///=============================== BOOL CGGBlueTooth::Create(int af/* = AF_BTH*/, int type/* = SOCK_STREAM*/, int protocol/* = BTHPROTO_RFCOMM*/) { if (m_hSocket) { return FALSE; } m_hSocket = socket(af, type, protocol); m_sktAddr.addressFamily = af; m_sktAddr.serviceClassId = GUID_NULL; return m_hSocket == INVALID_SOCKET ? FALSE : TRUE; } BOOL CGGBlueTooth::Close() { if (m_hSocket) { closesocket(m_hSocket); return TRUE; } return FALSE; } int CGGBlueTooth::Bind(BTH_ADDR sktAddr/* = 0*/, ULONG port/* = BT_PORT_ANY*/) { m_sktAddr.btAddr = sktAddr; m_sktAddr.port = port; return bind(m_hSocket, (SOCKADDR *)&m_sktAddr, sizeof(m_sktAddr)); } int CGGBlueTooth::Listen(int backlog) { return listen(m_hSocket, backlog); } int CGGBlueTooth::GetSockName(BTH_ADDR *psktAddr, ULONG *port) { int nLen = sizeof(m_sktAddr); int nResult = getsockname(m_hSocket, (SOCKADDR *)&m_sktAddr, &nLen); if (nResult == 0) { *psktAddr = m_sktAddr.btAddr; *port = m_sktAddr.port; } return nResult; } GUID OBEXFileTransferServiceClass_UUID_EX = { 0x00001106, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; int CGGBlueTooth::SetBthService(TCHAR * lpServiceName) { CSADDR_INFO sockInfo; sockInfo.iProtocol = BTHPROTO_RFCOMM; sockInfo.iSocketType = SOCK_STREAM; sockInfo.LocalAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr; sockInfo.LocalAddr.iSockaddrLength = sizeof(m_sktAddr); sockInfo.RemoteAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr; sockInfo.RemoteAddr.iSockaddrLength = sizeof(m_sktAddr); WSAQUERYSET svcInfo = { 0 }; svcInfo.dwSize = sizeof(svcInfo); svcInfo.dwNameSpace = NS_BTH; svcInfo.lpszServiceInstanceName = lpServiceName; svcInfo.lpServiceClassId = &OBEXFileTransferServiceClass_UUID_EX; svcInfo.dwNumberOfCsAddrs = 1; svcInfo.lpcsaBuffer = &sockInfo; return WSASetService(&svcInfo, RNRSERVICE_REGISTER, 0); } int CGGBlueTooth::Accept(CGGBlueTooth *pcBth) { SOCKADDR_BTH ca; int size = sizeof(ca); pcBth->m_hSocket = accept(m_hSocket, (SOCKADDR *)&ca, &size); pcBth->m_sktAddr = ca; return pcBth->m_hSocket == INVALID_SOCKET ? SOCKET_ERROR : 0; } int CGGBlueTooth::Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond/* = -1*/) { SOCKADDR_BTH sa = { 0 }; sa.addressFamily = AF_BTH; sa.btAddr = sktAddr; sa.port = port; if (nMSecond == -1) { return connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH)); } ULONG non_blocking = 1; ULONG blocking = 0; int nResult = ioctlsocket(m_hSocket, FIONBIO, &non_blocking); if (nResult == SOCKET_ERROR) { return nResult; } nResult = SOCKET_ERROR; if (connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR) { struct timeval tv; fd_set writefds; // 设置连接超时时间 tv.tv_sec = nMSecond / 1000; // 秒数 tv.tv_usec = nMSecond % 1000; // 毫秒 FD_ZERO(&writefds); FD_SET(m_hSocket, &writefds); nResult = select((int)m_hSocket + 1, NULL, &writefds, NULL, &tv); if (nResult > 0) { if (FD_ISSET(m_hSocket, &writefds)) { int error = 0; int len = sizeof(error); //下面的一句一定要,主要针对防火墙 if (!(getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0 || error != 0)) { nResult = 0; } } } else if (nResult == 0) { nResult = -2; } } if (ioctlsocket(m_hSocket, FIONBIO, &blocking) == SOCKET_ERROR) { nResult = SOCKET_ERROR; } return nResult; } int CGGBlueTooth::Send(LPVOID lpData, int len, int flags/* = 0*/) { return send(m_hSocket, (char *)lpData, len, flags); } int CGGBlueTooth::Recv(LPVOID lpData, int len, int flags/* = 0*/) { return recv(m_hSocket, (char *)lpData, len, flags); } int CGGBlueTooth::SendAll(LPVOID lpData, int len, int flags/* = 0*/) { int nCount = send(m_hSocket, (char *)lpData, len, flags); if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { return SOCKET_ERROR; } int nCommand = 0; nCount = recv(m_hSocket, (char *)&nCommand, 4, flags); if (nCount != 4 || nCommand != RECEIVE_OVER_COMMAND) { return SOCKET_ERROR; } return ERROR_SUCCESS; } int CGGBlueTooth::RecvAll(LPVOID lpData, int len, int flags/* = 0*/) { int nCount = -1, nCurRecv = 0, nMaxRead = 32 * 1024; while (nCurRecv < len) { if (len - nCurRecv < nMaxRead) { nMaxRead = len - nCurRecv; } nCount = recv(m_hSocket, (char *)lpData + nCurRecv, nMaxRead, flags); if (nCount == SOCKET_ERROR) { if (WSAGetLastError() == WSAEWOULDBLOCK) { Sleep(1); continue; } else { return SOCKET_ERROR; } } nCurRecv += nCount; } int nCommand = RECEIVE_OVER_COMMAND; nCount = send(m_hSocket, (char *)&nCommand, 4, flags); if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { return SOCKET_ERROR; } return ERROR_SUCCESS; }