最近项目中由于服务器端没有界面,所以需要实现网络通信来执行指令,这里简单记录一下。服务器端与客户端的搭建。
- 服务器端
1.1 使用VS2019创建项目
首先需要在VS2019中安装MFC的相关组件,通过visual studio installer即可快速安装。然后打开VS2019选择创建新项目->MFC应用,点击下一步。输入项目名称,选择项目存储位置,点击创建。注意这里将应用程序类型改为“基于对话框”,点击完成即可,如下图。
1.2 修改可视化界面
打开“资源视图”里面的ServerMFCApp下面的rc文件,选择Dialog,双击打开IDD_SERVERMFCAPP_DIALOG。把里面的控件都删除掉,设置成自己的。如下图。
然后双击Dialog中的启动按钮会自动生成事件处理方法,同样再点击发送按钮生成对应的处理方法。
1.3 ServerMFCAppDlg.h
// ServerMFCAppDlg.h: 头文件
//
#pragma once
#include "pch.h"
#include <iostream>
// CServerMFCAppDlg 对话框
class CServerMFCAppDlg : public CDialogEx
{
// 构造
public:
CServerMFCAppDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_SERVERMFCAPP_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
public:
SOCKET sock, ns;
bool isRunning, socketConnected = false; //1.是否处于启动状态 2.判断是否有客户端连接
bool init_network();//初始化并启动服务器
afx_msg void OnBnClickedBtnStart();//点击启动按钮
afx_msg void OnBnClickedBtnSend();//点击发送按钮
void onHandleMsg(std::string msg);
void sendMsg(char msg[]);
void show_logs(CString msg);
CListBox listLogs;
};
1.4 ServerMFCAppDlg.cpp
// ServerMFCAppDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "ServerMFCApp.h"
#include "afxdialogex.h"
#include "ServerMFCAppDlg.h"
#include "afxdialogex.h"
#define UM_SOCK WM_USER+100
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CServerMFCAppDlg 对话框
CServerMFCAppDlg::CServerMFCAppDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_SERVERMFCAPP_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CServerMFCAppDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_LOG, listLogs);
GetDlgItem(IDC_EDIT_PORT)->SetWindowText(CString("6543"));
}
BEGIN_MESSAGE_MAP(CServerMFCAppDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_START, &CServerMFCAppDlg::OnBnClickedBtnStart)
ON_BN_CLICKED(IDC_BTN_SEND, &CServerMFCAppDlg::OnBnClickedBtnSend)
END_MESSAGE_MAP()
// CServerMFCAppDlg 消息处理程序
BOOL CServerMFCAppDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
LRESULT CServerMFCAppDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
SOCKET s;
int wmEvent;
int len, remote_len;
struct sockaddr_in remote;
char text[30] = { };
switch (message) {
case UM_SOCK:
s = (SOCKET)wParam;
wmEvent = LOWORD(lParam);
switch (wmEvent) {
case FD_ACCEPT:
show_logs(CString("已连接!"));
len = sizeof(remote);
ns = accept(s, (sockaddr*)&remote, &len);
if (ns == SOCKET_ERROR) {
this->socketConnected = false;
closesocket(s);
sock = 0;
show_logs(CString("连接已关闭,请重启!"));
break;
}
this->socketConnected = true;
WSAAsyncSelect(ns, m_hWnd, UM_SOCK, FD_READ | FD_CLOSE);
break;
case FD_READ:
len = recv(s, text, 30, 0);
if (len <= 0) {
break;
}
onHandleMsg(text);
//MessageBox(cmd, _T(""), MB_OK);
break;
case FD_CLOSE:
show_logs(CString("客户端断开连接!"));
//MessageBox(_T("socket closed\n"), NULL, MB_OK);
this->socketConnected = false;
closesocket(ns);
closesocket(s);
break;
default:
break;
}
break;
default:
return CDialog::WindowProc(message, wParam, lParam);
}
return 0;
}
void CServerMFCAppDlg::onHandleMsg(std::string msg)
{
//MessageBox(CString(msg.c_str()), _T(""), MB_OK);
if (msg == "3") //拍照
{
show_logs(CString("收到客户端发来的信息:请求拍照!"));
sendMsg("300");
}
else if (msg == "0")//打开相机
{
show_logs(CString("收到客户端发来的信息:请求打开相机!"));
sendMsg("000");
}
else if (msg == "1")//关闭相机
{
show_logs(CString("收到客户端发来的信息:请求关闭相机!"));
sendMsg("100");
}
else if (msg == "2")//录制视频
{
show_logs(CString("收到客户端发来的信息:请求录像!"));
sendMsg("200");
}
else if (msg == "4")//录制视频
{
show_logs(CString("收到客户端发来的信息:请求停止录像!"));
sendMsg("400");
}
else if (msg == "5")//检查相机是否已打开
{
sendMsg("000");
}
else//错误命令
{
sendMsg("500");
}
}
bool CServerMFCAppDlg::init_network()
{
WSADATA wsaData;
//初始化TCP协议
BOOL ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (ret != 0)
{
MessageBox(_T("初始化网络协议失败!"), _T("提示"));
return false;
}
//创建服务器端套接字
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
MessageBox(_T("创建套接字失败!"), _T("提示"));
closesocket(sock);
return false;
}
//绑定到本地一个端口上
sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(6543); //端口号不要与其他应用程序冲突
localaddr.sin_addr.s_addr = 0;
if (bind(sock, (struct sockaddr*) & localaddr, sizeof(sockaddr)) \
== SOCKET_ERROR)
{
MessageBox(_T("绑定地址失败!"), _T("提示"));
closesocket(sock);
return false;
}
//将SeverSock设置为异步非阻塞模式,并为它注册各种网络异步事件,其中m_hWnd
//为应用程序的主对话框或主窗口的句柄
if (WSAAsyncSelect(sock, m_hWnd, UM_SOCK, FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox(_T("注册网络异步事件失败!"), _T("提示"));
closesocket(sock);
return false;
}
this->isRunning = true;
listen(sock, 5);
return true;
}
void CServerMFCAppDlg::sendMsg(char msg[])
{
if (!this->isRunning)
{
show_logs(CString("服务器未启动!"));
return;
}
if (!this->socketConnected)
{
show_logs(CString("没有客户端连接!"));
return;
}
int strLen = send(ns, msg, sizeof(msg), 0);
if (strLen == -1)
show_logs(CString("未知错误,命令发送失败!"));
}
void CServerMFCAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CServerMFCAppDlg::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 CServerMFCAppDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CServerMFCAppDlg::OnBnClickedBtnStart()
{
// TODO: 在此添加控件通知处理程序代码
if (this->isRunning)
{
closesocket(sock);
}
else
{
show_logs(CString("正在启动服务器..."));
if (init_network())
{
this->isRunning = true;
SetDlgItemText(IDC_BTN_START, CString("停止"));
show_logs(CString("服务器已启动...在6543端口监听"));
}
else
{
this->isRunning = false;
SetDlgItemText(IDC_BTN_START, CString("启动"));
show_logs(CString("服务器启动失败!请重试!"));
}
}
}
void CServerMFCAppDlg::show_logs(CString msg)
{
listLogs.AddString(msg);
listLogs.SetTopIndex(listLogs.GetCount() - 1);
}
void CStringToChar(CString str, char ch[])
{
char* tmpch;
int wLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
tmpch = new char[wLen + 1];
WideCharToMultiByte(CP_ACP, 0, str, -1, tmpch, wLen, NULL, NULL);
for (int i = 0; i < wLen; ++i)
ch[i] = tmpch[i];
}
void CServerMFCAppDlg::OnBnClickedBtnSend()
{
// TODO: 在此添加控件通知处理程序代码
CString msg;
GetDlgItem(IDC_EDIT_MSG)->GetWindowText(msg);
if (msg.GetLength() == 0)
{
show_logs(CString("发送信息不能为空!"));
return;
}
char chMsg[100];
CStringToChar(msg, chMsg);
show_logs(CString(chMsg));
sendMsg(chMsg);
}
1.5 运行服务端
我这里的项目配置的是release以及x64的运行环境,点击本地windows调试器运行,报错如下。
处理办法:在项目资源管理器中的项目名称上右键选择属性,将C/C++选项下的sdl检查调为否(最好是debug和release都调一下),如下图。
-
客户端
2.1 创建客户端项目
参照前面客户端部分的创建,只是名字不同,我这里用的名字是ClientMFCApp。
2.2 修改可视化界面
2.3 ClientMFCAppDlg.h
// ClientMFCAppDlg.h: 头文件
//
#pragma once
#include<iostream>
// CClientMFCAppDlg 对话框
class CClientMFCAppDlg : public CDialogEx
{
// 构造
public:
CClientMFCAppDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_CLIENTMFCAPP_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
bool isConnect = false;
bool isOpenCamera = false;
bool isRecord = false;
bool isRegRecvEvent = false;
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
afx_msg void OnBnClickedBtnCapture();
afx_msg void OnBnClickedBtnConnect();
afx_msg void OnBnClickedBtnOpenCap();
afx_msg void OnBnClickedBtnRecVideo();
void regRecvEvent();
bool connect2Server();
void handleRecvMsg(std::string text);
bool sendMsg(char msg[]);
void show_tips(CString msg);
// 状态提示
CListBox listTips;
};
2.4 ClientMFCAppDlg.cpp
// ClientMFCAppDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "ClientMFCApp.h"
#include "ClientMFCAppDlg.h"
#include "afxdialogex.h"
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<afxwin.h>
#include<iostream>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
static UINT RecvEvent(LPVOID P);
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
CClientMFCAppDlg* pDlg;
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CClientMFCAppDlg 对话框
CClientMFCAppDlg::CClientMFCAppDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_CLIENTMFCAPP_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CClientMFCAppDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_TIPS, listTips);
GetDlgItem(IDC_EDIT_IP)->SetWindowText(CString("127.0.0.1"));
GetDlgItem(IDC_EDIT_PORT)->SetWindowText(CString("6543"));
}
BEGIN_MESSAGE_MAP(CClientMFCAppDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_CAPTURE, &CClientMFCAppDlg::OnBnClickedBtnCapture)
ON_BN_CLICKED(IDC_BTN_CONNECT, &CClientMFCAppDlg::OnBnClickedBtnConnect)
ON_BN_CLICKED(IDC_BTN_OPEN_CAP, &CClientMFCAppDlg::OnBnClickedBtnOpenCap)
ON_BN_CLICKED(IDC_BTN_REC_VIDEO, &CClientMFCAppDlg::OnBnClickedBtnRecVideo)
END_MESSAGE_MAP()
// CClientMFCAppDlg 消息处理程序
BOOL CClientMFCAppDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CClientMFCAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CClientMFCAppDlg::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 CClientMFCAppDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
/*
msg == "3" //拍照
msg == "0" //打开相机
msg == "1" //关闭相机
msg == "2" //录制视频
*/
void CClientMFCAppDlg::OnBnClickedBtnCapture()
{
// TODO: 在此添加控件通知处理程序代码
if (this->isOpenCamera)
{
show_tips(CString("请求拍照中..."));
sendMsg("3");
}
else
{
show_tips(CString("请先打开摄像头!"));
}
}
void CClientMFCAppDlg::OnBnClickedBtnConnect()
{
// TODO: 在此添加控件通知处理程序代码
if (this->isConnect)
{
this->isRegRecvEvent = false;
this->isConnect = false;
closesocket(hSocket);
show_tips(CString("已断开连接!"));
SetDlgItemText(IDC_BTN_CONNECT, CString("连接服务器"));
}
else
{
if (connect2Server())
{
SetDlgItemText(IDC_BTN_CONNECT, CString("断开连接"));
}
else
{
SetDlgItemText(IDC_BTN_CONNECT, CString("连接服务器"));
}
}
}
void CClientMFCAppDlg::OnBnClickedBtnOpenCap()
{
// TODO: 在此添加控件通知处理程序代码
if (this->isOpenCamera)
{
show_tips(CString("正在请求关闭摄像头..."));
sendMsg("1");
Sleep(1000);
}
else
{
show_tips(CString("正在请求打开摄像头..."));
sendMsg("0");
Sleep(1000);
}
}
void CClientMFCAppDlg::OnBnClickedBtnRecVideo()
{
if (this->isOpenCamera)
{
if (isRecord)
{
show_tips(CString("正在请求结束视频录制..."));
sendMsg("4");
}else
{
show_tips(CString("正在请求录制视频..."));
sendMsg("2");
}
}
else
{
show_tips(CString("请先打开摄像头!"));
}
}
void SplitCString(const CString& _cstr, const CString& _flag, CStringArray& _resultArray)
{
CString strSrc(_cstr);
CStringArray& strResult = _resultArray;
CString strLeft = _T("");
int nPos = strSrc.Find(_flag);
while (0 <= nPos)
{
strLeft = strSrc.Left(nPos);
if (!strLeft.IsEmpty())
{
strResult.Add(strLeft);
}
strSrc = strSrc.Right(strSrc.GetLength() - nPos - 1);
nPos = strSrc.Find(_flag);
}
if (!strSrc.IsEmpty()) {
strResult.Add(strSrc);
}
}
bool CClientMFCAppDlg::connect2Server()
{
int strLen;
CString ip;
CStringArray _resultArray;
GetDlgItem(IDC_EDIT_IP)->GetWindowText(ip);
SplitCString(ip, CString("."), _resultArray);
if (_resultArray.GetSize() != 4)
{
show_tips(CString("主机地址输入有误!"));
return false;
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
show_tips(CString("WSA启动错误!"));
return false;
}
hSocket = socket(AF_INET, SOCK_STREAM, 0);
if (hSocket == INVALID_SOCKET)
{
show_tips(CString("INVALID SOCKET!"));
return false;
}
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
InetPton(AF_INET, ip, &servAddr.sin_addr.s_addr);
servAddr.sin_port = htons(6543);
if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
show_tips(CString("连接服务器失败!"));
return false;
}
this->isConnect = true;
show_tips(CString("已连接到服务器,请打开摄像头!"));
regRecvEvent();
sendMsg("5");
return true;
}
void CClientMFCAppDlg::show_tips(CString msg)
{
listTips.AddString(msg);
listTips.SetTopIndex(listTips.GetCount() - 1);
}
bool CClientMFCAppDlg::sendMsg(char msg[])
{
if (!isConnect)
{
show_tips(CString("未连接到服务器!"));
return false;
}
int strLen = send(hSocket, msg, sizeof(msg), 0);
if (strLen == -1)
show_tips(CString("未知错误,命令发送失败!"));
}
void CClientMFCAppDlg::regRecvEvent()
{
this->isRegRecvEvent = true;
CWinThread* thread = AfxBeginThread(RecvEvent, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);//返回线程句柄
}
/*
msg == "0" //打开相机 000 打开摄像头成功 001 打开摄像头失败
msg == "1" //关闭相机 100 关闭摄像头成功
msg == "2" //录制视频 200 开始录制视频
msg == "3" //拍照 300 拍照成功
msg == "4" //停止录制 400 录制视频完成
*/
void CClientMFCAppDlg::handleRecvMsg(string text)
{
//MessageBox(CString(text.c_str()), _T("1"));
CString tmp("收到服务器发来的信息:");
tmp.Append(CString(text.c_str()));
show_tips(tmp);
if (text == "000")
{
this->isOpenCamera = true;
show_tips(CString("摄像头已打开!"));
SetDlgItemText(IDC_BTN_OPEN_CAP, CString("关闭摄像头"));
}
else if (text == "001")
{
this->isOpenCamera = false;
show_tips(CString("摄像头处于关闭状态!"));
SetDlgItemText(IDC_BTN_OPEN_CAP, CString("打开摄像头"));
}
else if (text == "100")
{
this->isOpenCamera = false;
show_tips(CString("摄像头已关闭!"));
SetDlgItemText(IDC_BTN_OPEN_CAP, CString("打开摄像头"));
}
else if (text == "200")
{
this->isRecord = true;
show_tips(CString("开始录制视频!"));
SetDlgItemText(IDC_BTN_REC_VIDEO, CString("结束录制"));
}
else if (text == "300")
{
show_tips(CString("拍照完成!"));
}
else if (text == "400")
{
this->isRecord = false;
show_tips(CString("视频录制完成!"));
SetDlgItemText(IDC_BTN_REC_VIDEO, CString("录制视频"));
}
}
UINT RecvEvent(LPVOID p)
{
int len = 0;
char text[30] = { };
pDlg = (CClientMFCAppDlg*)p;
while (pDlg->isRegRecvEvent)
{
len = recv(pDlg->hSocket, text, 30, 0);
if (len <= 0) {
continue;
}
pDlg->handleRecvMsg(text);
}
return 0LU;
}