VC++:汉王人脸通SDK示例代码(三)接收心跳包

同系列文章:

运行环境

下载安装Visual C++ Redistributable for Visual Studio 2015

演示程序源代码下载:

FaceIdDemo-VC2015-20161118.zip
注意:请将FaceId.dll和FaceId.lib拷贝到Release和Debug目录下

演示程序界面:
UdpServerDemo-VC

示例代码
UdpServerDemoDlg.h


// UdpServerDemoDlg.h : 头文件
//

#pragma once

#include "..\\FaceId\\Source\\UdpClientPlus.h"
#include <list>

// CUdpServerDemoDlg 对话框
class CUdpServerDemoDlg : public CDialogEx, IDgramPacketHandler
{
// 构造
public:
	CUdpServerDemoDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_UDPSERVERDEMO_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedButtonclear();
	afx_msg void OnBnClickedButtonstart();
	afx_msg void OnDestroy();

private:
	// IDgramPacketHandler接口实现
	BOOL IsTrustedIPAddress(const CHAR* IPAddress);	
	VOID OnDgramPacketReceived(const SOCKADDR_STORAGE* FromSA, const BYTE* PacketContent, INT ReceivedBytes);
	VOID OnDgramPacketReceived(const SOCKADDR_STORAGE* FromSA, const TCHAR* PacketContent, INT ReceivedChars);

private:
	BOOL IsServerRunning = FALSE;	// 服务器是否已经运行
	UdpClientPlus* UdpServer;		// 心跳包接收服务器
	std::list<std::string>* TrustedIPAddresses = NULL;	// 可信IP地址列表

	CString HeartBeatRecord;	// 显示心跳数据

private:
	CONST UINT DeviceCodePage = 936;	// 设备通信字符集为简体中文
public:
	afx_msg void OnBnClickedButtonsetserver();
};

UdpServerDemoDlg.cpp

/* ----------------------------------------------------------
* 文件名称:UdpServerDemoDlg.cpp
*
* 作者:秦建辉
*
* QQ:36748897
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
*      Visual Studio V2013
*
* 版本历史:
*	V1.0    2014年09月24日
*           VC:人脸通SDK示例代码-接收心跳包
* ------------------------------------------------------------ */

// UdpServerDemoDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "UdpServerDemo.h"
#include "UdpServerDemoDlg.h"
#include "afxdialogex.h"
#include "..\\FaceId\\\Source\\SocketUtils.h"
#include "..\\FaceId\\Source\\FaceId.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#ifdef _DEBUG
#pragma comment(lib, "..\\Debug\\FaceId.lib")
#else
#pragma comment(lib, "..\\Release\\FaceId.lib")
#endif

// CUdpServerDemoDlg 对话框



CUdpServerDemoDlg::CUdpServerDemoDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CUdpServerDemoDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CUdpServerDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CUdpServerDemoDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTONCLEAR, &CUdpServerDemoDlg::OnBnClickedButtonclear)
	ON_BN_CLICKED(IDC_BUTTONSTART, &CUdpServerDemoDlg::OnBnClickedButtonstart)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTONSETSERVER, &CUdpServerDemoDlg::OnBnClickedButtonsetserver)
END_MESSAGE_MAP()


// CUdpServerDemoDlg 消息处理程序

BOOL CUdpServerDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// 设置参数
	SetDlgItemText(IDC_EDITDEVICEIP, TEXT("192.168.1.18"));	// 设置设备地址
	SetDlgItemInt(IDC_EDITDEVICEPORT, 9922, FALSE);	// 设备默认端口	
	SetDlgItemInt(IDC_EDITHEARTSERVERPORT, 9904, FALSE);

	// 设置服务器地址
	std::list<SOCKADDR*> AddrList;
	if (StringToSockAddrSet(TEXT(""), 0, AddrList, AF_INET) == 0)
	{
		std::list<SOCKADDR*>::iterator first = AddrList.begin(), last = AddrList.end();
		TCHAR StringBuffer[64];
		CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBOHEARTSERVERIP);	// 注意设置Sort为FALSE
		while (first != last)
		{
			if (SockAddrToIPString(*first, StringBuffer, _countof(StringBuffer)) == 0)
			{
				pComboBox->AddString(StringBuffer);
			}
			first++;
		}

		INT n = pComboBox->GetCount();
		if (n > 0)
		{	// 设置当前选择
			pComboBox->SetCurSel(0);

			// 如果一个IP,禁止选择
			if (n == 1) pComboBox->EnableWindow(FALSE);
		}
		
		// 释放内存
		first = AddrList.begin();
		while (first != last)
		{
			delete *first;
			first++;
		}
		AddrList.clear();
	}

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CUdpServerDemoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CUdpServerDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

// 清空文本框文本
void CUdpServerDemoDlg::OnBnClickedButtonclear()
{
	SetDlgItemText(IDC_EDITDATA, TEXT(""));
	HeartBeatRecord = TEXT("");
}

// 开启/关闭侦听服务器
void CUdpServerDemoDlg::OnBnClickedButtonstart()
{
	if (IsServerRunning)
	{	// 释放侦听器
		if (UdpServer != NULL)
		{
			delete UdpServer;
			UdpServer = NULL;
		}

		IsServerRunning = FALSE;
		SetDlgItemText(IDC_BUTTONSTART, TEXT("开启侦听"));
	}
	else
	{
		try
		{	// 获取服务器地址
			TCHAR ServerIP[64];
			GetDlgItemText(IDC_COMBOHEARTSERVERIP, ServerIP, _countof(ServerIP));
			UdpServer = new UdpClientPlus(ServerIP, GetDlgItemInt(IDC_EDITHEARTSERVERPORT), AF_INET, TRUE);
		}	
		catch (DWORD dwErrorCode)
		{
			TCHAR Information[256];
			StringCchPrintf(Information, _countof(Information), TEXT("错误代码:%d"), dwErrorCode);
			MessageBox(Information, TEXT("错误"), MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
			return;
		}

		//	设置通信密码
		UdpServer->SetSecretKey(NULL);	// 注意:通信密码要和设备一致

		// 设置代码页
		UdpServer->CodePage = DeviceCodePage;

		// 开启侦听服务
		DWORD ErrorCode = UdpServer->StartListenThread(this, 0);
		if (ErrorCode == ERROR_SUCCESS)
		{
			IsServerRunning = TRUE;
			SetDlgItemText(IDC_BUTTONSTART, TEXT("关闭侦听"));
		}
		else
		{
			MessageBox(TEXT("启动心跳包服务器失败!"), TEXT("错误"), MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
			if (UdpServer != NULL)
			{
				delete UdpServer;
				UdpServer = NULL;
			}
		}
	}
}

void CUdpServerDemoDlg::OnDestroy()
{
	__super::OnDestroy();

	// 释放监听器
	if (UdpServer != NULL)
	{
		delete UdpServer;
		UdpServer = NULL;
	}

	// 释放可信IP地址列表
	if (TrustedIPAddresses != NULL)
	{
		delete TrustedIPAddresses;
		TrustedIPAddresses = NULL;
	}
}

// 判断是否是可信的IP地址
BOOL CUdpServerDemoDlg::IsTrustedIPAddress(const CHAR* IPAddress)
{
	if (TrustedIPAddresses == NULL)
	{
		return TRUE;
	}
	else
	{
		std::list<std::string>::const_iterator Begin = TrustedIPAddresses->begin();
		std::list<std::string>::const_iterator End = TrustedIPAddresses->end();
		if (std::find(Begin, End, IPAddress) == End)
			return FALSE;
		else
			return TRUE;
	}
}

VOID CUdpServerDemoDlg::OnDgramPacketReceived(const SOCKADDR_STORAGE* FromSA, const BYTE* PacketContent, INT ReceivedBytes)
{
	return;
}

VOID CUdpServerDemoDlg::OnDgramPacketReceived(const SOCKADDR_STORAGE* FromSA, const TCHAR* PacketContent, INT ReceivedChars)
{
	// 显示IP地址
	TCHAR Buffer[64];
	if (SockAddrToIPString((SOCKADDR*)FromSA, Buffer, _countof(Buffer)) == ERROR_SUCCESS)
	{
		HeartBeatRecord.AppendFormat(TEXT("%s\r\n"), Buffer);
	}
	else
	{
		HeartBeatRecord.AppendFormat(TEXT("**********\r\n"));
	}

	// 显示接收内容
	HeartBeatRecord.AppendFormat(TEXT("%s\r\n"), PacketContent);
	SetDlgItemText(IDC_EDITDATA, HeartBeatRecord);
}

void CUdpServerDemoDlg::OnBnClickedButtonsetserver()
{
	// 连接设备
	FaceId* TcpClient = NULL;
	try
	{
		TCHAR DeviceIP[64];
		GetDlgItemText(IDC_EDITDEVICEIP, DeviceIP, _countof(DeviceIP));
		TcpClient = new FaceId(DeviceIP, GetDlgItemInt(IDC_EDITDEVICEPORT));
	}
	catch (DWORD dwErrorCode)
	{
		TCHAR Information[256];
		StringCchPrintf(Information, _countof(Information), TEXT("错误代码:%d"), dwErrorCode);
		MessageBox(Information, TEXT("错误"), MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
		return;
	}

	// 设置服务器
	TCHAR ServerIP[64];
	GetDlgItemText(IDC_COMBOHEARTSERVERIP, ServerIP, _countof(ServerIP));

	TCHAR Command[256];
	StringCchPrintf(Command, _countof(Command), TEXT("SetServerHost(ip=\"%s\" port=\"%d\")"), ServerIP, GetDlgItemInt(IDC_EDITHEARTSERVERPORT));

	tstring Answer;
	INT ReceivedChars = TcpClient->Execute(Command, Answer, DeviceCodePage);
	if (ReceivedChars > 0)
	{
		MessageBox(TEXT("设置服务器成功!"), TEXT("成功"), MB_OK | MB_ICONINFORMATION | MB_DEFBUTTON1);
	}
	else
	{
		StringCchPrintf(Command, _countof(Command), TEXT("设置服务器失败!错误代码=%d"), ReceivedChars);
		MessageBox(Command, TEXT("失败"), MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
	}

	// 断开连接
	TcpClient->Close();
	delete TcpClient;
}

Comments are closed.