要结束对Winsock服务的使用,调用WSACleanup函数。在程序中对每个成功调用的WSAStartup都必须对应地调用WSACleanup。
以下是客户端连接服务端蓝牙代码:
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <ws2bth.h>
//1.初始化winsock库
BOOL CBlueTooth::InitSocket()
{
// 初始化winsock
WSADATA wsaData;
if( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
{
//Socket 库初始化失败!
WSACleanup();
return FALSE;
}
//确认持WinSock DLL是否支 2.2版本
if(2 != HIBYTE(wsaData.wVersion) || 2 != LOBYTE(wsaData.wVersion))
{
//windows Socket 版本不支持
WSACleanup();
return FALSE;
}
return TRUE;
}
BOOL CDemoDlg::ConnectBlueTooth(BTH_ADDR sktAddr)//蓝牙地址
{
//创建蓝牙套接字
SOCKET m_hSocket = socket(AF_BTH,SOCK_STREAM,BTHPROTO_RFCOMM);
if(!m_hSocket)
{
CloseHandle ((LPVOID)m_hSocket);
return FALSE;
}
int nMSecond = -1;
SOCKADDR_BTH sa = { 0 };
sa.addressFamily = AF_BTH;
sa.btAddr = sktAddr;
sa.port = 1; //端口
if (nMSecond == -1)
{
int num = connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH));
if(num ==SOCKET_ERROR)
{
ErrorNum = WSAGetLastError();
}
else
return 0;
}
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;
}