蓝牙socket的recv()有关问题
蓝牙socket的recv()问题 - C++ Builder / Windows SDK/API
在Windows Mobile6.1系统上做蓝牙,使用socket。
现在搜索、连接、发送都没有问题。接收用的是recv()堵塞,现在的情况是:能收到数据,但每次收几个字节就通知我,完整的一帧(自定义的)要分好多次才能收完。例如发送1234567890,会先收一个字节“1”,再收“234567”,再收“890”这样。
想请教一下,是不是什么参数我没有设置?堵塞接收怎样才能一次接收成功完整的一帧?
源码如下:[code=C/C++][/code]
//
#include <Bt_api.h.>
#include <winioctl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define lengthof(exp) ((sizeof((exp)))/sizeof((*(exp))))
#define IOCTL_SERVICE_START CTL_CODE(FILE_DEVICE_SERVICE, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SERVICE_STOP CTL_CODE(FILE_DEVICE_SERVICE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SERVICE_REFRESH CTL_CODE(FILE_DEVICE_SERVICE, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
//////////////////////////////////////////////////////////////////////////
//
GUID RFCOMM_PROTOCOL_UUID = {0x00001101, 0x0000, 0x1000, {0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}};
HKEY m_hKey;
//
HWND m_hwnd_List_Find;
TCHAR wRbuf[64];
//
#define NS_BTH 16
//
#define MAX_NAME 248
//
//
SOCKET m_socket;
//
//
LPWSAQUERYSET pwsaResults;
//
CStringArray csar;
unsigned short g_port;
UINT m_LinkState; //连接活动进行到什么状态
#define DEFAULT_PORT 1
//保存蓝牙设备 BT_ADDR
CArray<BT_ADDR, BT_ADDR> arb;
HWND hWnd;
BOOL nExit = FALSE;
HANDLE hThread = INVALID_HANDLE_VALUE;
static DWORD WINAPI ReadThread( PVOID pArg );
IMPLEMENT_DYNCREATE(CBthOpe4View, CFormView)
BEGIN_MESSAGE_MAP(CBthOpe4View, CFormView)
ON_BN_CLICKED(IDC_BUT_FIND, &CBthOpe4View::OnBnClickedButFind)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BUT_LINK, &CBthOpe4View::OnBnClickedButLink)
ON_BN_CLICKED(IDC_BTN_SEND, &CBthOpe4View::OnBnClickedBtnSend)
ON_WM_TIMER()
END_MESSAGE_MAP()
// CBthOpe4View 构造/析构
CBthOpe4View::CBthOpe4View()
: CFormView(CBthOpe4View::IDD)
{
// TODO: 在此处添加构造代码
}
CBthOpe4View::~CBthOpe4View()
{
}
void CBthOpe4View::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
}
BOOL CBthOpe4View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CFormView::PreCreateWindow(cs);
}
void CBthOpe4View::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
m_LinkState = 0;
SetTimer(1,100,NULL);
GetDlgItem( IDC_LIST_FIND, &m_hwnd_List_Find );
WSADATA wsd;
int ret = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
WCHAR *argPtr = _T("card");
HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE, //打开电源
FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, 0, NULL);
if (hDev != INVALID_HANDLE_VALUE)
{
int iErr = DeviceIoControl (hDev, IOCTL_SERVICE_START, argPtr, sizeof(WCHAR) * (wcslen (argPtr) + 1), NULL, NULL, NULL, NULL);
CloseHandle (hDev);
}
nExit = TRUE;
hThread = CreateThread(NULL,0, ReadThread,NULL, 0,NULL);
Sleep(1000);
}
// CBthOpe4View 诊断
#ifdef _DEBUG
void CBthOpe4View::AssertValid() const
{
CFormView::AssertValid();
}
CBthOpe4Doc* CBthOpe4View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBthOpe4Doc)));
return (CBthOpe4Doc*)m_pDocument;
}
#endif //_DEBUG
// CBthOpe4View 消息处理程序
void CBthOpe4View::OnBnClickedButFind()
{
// TODO: 在此添加控件通知处理程序代码
if ( TRUE == m_BSoketFlag )
{
m_BSoketFlag = FALSE;
closesocket( m_socket );
}
((CListBox*)GetDlgItem(IDC_LIST_FIND))->ResetContent();
在Windows Mobile6.1系统上做蓝牙,使用socket。
现在搜索、连接、发送都没有问题。接收用的是recv()堵塞,现在的情况是:能收到数据,但每次收几个字节就通知我,完整的一帧(自定义的)要分好多次才能收完。例如发送1234567890,会先收一个字节“1”,再收“234567”,再收“890”这样。
想请教一下,是不是什么参数我没有设置?堵塞接收怎样才能一次接收成功完整的一帧?
源码如下:[code=C/C++][/code]
//
#include <Bt_api.h.>
#include <winioctl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define lengthof(exp) ((sizeof((exp)))/sizeof((*(exp))))
#define IOCTL_SERVICE_START CTL_CODE(FILE_DEVICE_SERVICE, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SERVICE_STOP CTL_CODE(FILE_DEVICE_SERVICE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SERVICE_REFRESH CTL_CODE(FILE_DEVICE_SERVICE, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
//////////////////////////////////////////////////////////////////////////
//
GUID RFCOMM_PROTOCOL_UUID = {0x00001101, 0x0000, 0x1000, {0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}};
HKEY m_hKey;
//
HWND m_hwnd_List_Find;
TCHAR wRbuf[64];
//
#define NS_BTH 16
//
#define MAX_NAME 248
//
//
SOCKET m_socket;
//
//
LPWSAQUERYSET pwsaResults;
//
CStringArray csar;
unsigned short g_port;
UINT m_LinkState; //连接活动进行到什么状态
#define DEFAULT_PORT 1
//保存蓝牙设备 BT_ADDR
CArray<BT_ADDR, BT_ADDR> arb;
HWND hWnd;
BOOL nExit = FALSE;
HANDLE hThread = INVALID_HANDLE_VALUE;
static DWORD WINAPI ReadThread( PVOID pArg );
IMPLEMENT_DYNCREATE(CBthOpe4View, CFormView)
BEGIN_MESSAGE_MAP(CBthOpe4View, CFormView)
ON_BN_CLICKED(IDC_BUT_FIND, &CBthOpe4View::OnBnClickedButFind)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BUT_LINK, &CBthOpe4View::OnBnClickedButLink)
ON_BN_CLICKED(IDC_BTN_SEND, &CBthOpe4View::OnBnClickedBtnSend)
ON_WM_TIMER()
END_MESSAGE_MAP()
// CBthOpe4View 构造/析构
CBthOpe4View::CBthOpe4View()
: CFormView(CBthOpe4View::IDD)
{
// TODO: 在此处添加构造代码
}
CBthOpe4View::~CBthOpe4View()
{
}
void CBthOpe4View::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
}
BOOL CBthOpe4View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CFormView::PreCreateWindow(cs);
}
void CBthOpe4View::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
m_LinkState = 0;
SetTimer(1,100,NULL);
GetDlgItem( IDC_LIST_FIND, &m_hwnd_List_Find );
WSADATA wsd;
int ret = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
WCHAR *argPtr = _T("card");
HANDLE hDev = CreateFile (L"BTD0:", GENERIC_READ | GENERIC_WRITE, //打开电源
FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, 0, NULL);
if (hDev != INVALID_HANDLE_VALUE)
{
int iErr = DeviceIoControl (hDev, IOCTL_SERVICE_START, argPtr, sizeof(WCHAR) * (wcslen (argPtr) + 1), NULL, NULL, NULL, NULL);
CloseHandle (hDev);
}
nExit = TRUE;
hThread = CreateThread(NULL,0, ReadThread,NULL, 0,NULL);
Sleep(1000);
}
// CBthOpe4View 诊断
#ifdef _DEBUG
void CBthOpe4View::AssertValid() const
{
CFormView::AssertValid();
}
CBthOpe4Doc* CBthOpe4View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBthOpe4Doc)));
return (CBthOpe4Doc*)m_pDocument;
}
#endif //_DEBUG
// CBthOpe4View 消息处理程序
void CBthOpe4View::OnBnClickedButFind()
{
// TODO: 在此添加控件通知处理程序代码
if ( TRUE == m_BSoketFlag )
{
m_BSoketFlag = FALSE;
closesocket( m_socket );
}
((CListBox*)GetDlgItem(IDC_LIST_FIND))->ResetContent();