zoukankan      html  css  js  c++  java
  • MFC- 网络编程

    一、MFC网络编程

    a)CAsyncSocket用于异步非阻塞类,用UDP通信;

    b)CAsyncSocket的子类(派生类);Csocket同步阻塞类,用于TCP通信;

    c)通信前,必须调用AfxSocketInit()进行初始化

    二、CAsyncSocket类UDP通信

    2.1 服务器端通信步骤:

    a)在.h文件中创建CAsyncSocket类对象;

    b)创建套接字CAsyncSocket::Create();

    c)发送数据CAsyncSocket::SentTo();

    d)关闭套接字CAsyncSocket::Close();

    2.2 MFC界面

    2.3 代码实例:

    a)01_UDPServerDlg.h中添加CAsyncSocket对象

     1 // 01_UDPServerDlg.h : 头文件
     2 //
     3 
     4 #pragma once
     5 #include "afxcmn.h"
     6 #include "afxwin.h"
     7 
     8 
     9 // CMy01_UDPServerDlg 对话框
    10 class CMy01_UDPServerDlg : public CDialogEx
    11 {
    12 // 构造
    13 public:
    14     CMy01_UDPServerDlg(CWnd* pParent = NULL);    // 标准构造函数
    15 
    16 // 对话框数据
    17     enum { IDD = IDD_MY01_UDPSERVER_DIALOG };
    18 
    19     protected:
    20     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    21 
    22 
    23 // 实现
    24 protected:
    25     HICON m_hIcon;
    26 
    27     // 生成的消息映射函数
    28     virtual BOOL OnInitDialog();
    29     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    30     afx_msg void OnPaint();
    31     afx_msg HCURSOR OnQueryDragIcon();
    32     DECLARE_MESSAGE_MAP()
    33 private:
    34     //自定义添加代码,MFC界面对应控件变量
    35     UINT peerPort;
    36     UINT localPort;
    37     CIPAddressCtrl addrCtrl;
    38     CString sendBuf;
    39     int sendLen;
    40     CButton startButton;
    41     CButton stopButton;
    42 
    43     //套接字对象
    44     CAsyncSocket socket;
    45 public:
    46     afx_msg void OnBnClickedButton1();
    47     afx_msg void OnTimer(UINT_PTR nIDEvent);
    48     afx_msg void OnBnClickedButton2();
    49 };
    View Code

    b)01_UDPServerDlg.cpp中初始化各变量,并实现通信套接字的创建,接受及关闭

      1 // 01_UDPServerDlg.cpp : 实现文件
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "01_UDPServer.h"
      6 #include "01_UDPServerDlg.h"
      7 #include "afxdialogex.h"
      8 
      9 #ifdef _DEBUG
     10 #define new DEBUG_NEW
     11 #endif
     12 
     13 
     14 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
     15 
     16 class CAboutDlg : public CDialogEx
     17 {
     18 public:
     19     CAboutDlg();
     20 
     21 // 对话框数据
     22     enum { IDD = IDD_ABOUTBOX };
     23 
     24     protected:
     25     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
     26 
     27 // 实现
     28 protected:
     29     DECLARE_MESSAGE_MAP()
     30 };
     31 
     32 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
     33 {
     34 }
     35 
     36 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
     37 {
     38     CDialogEx::DoDataExchange(pDX);
     39 }
     40 
     41 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
     42 END_MESSAGE_MAP()
     43 
     44 
     45 // CMy01_UDPServerDlg 对话框
     46 
     47 
     48 
     49 CMy01_UDPServerDlg::CMy01_UDPServerDlg(CWnd* pParent /*=NULL*/)
     50     : CDialogEx(CMy01_UDPServerDlg::IDD, pParent)
     51     , peerPort(0)
     52     , localPort(0)
     53     , sendBuf(_T(""))
     54     , sendLen(0)
     55 {
     56     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
     57 }
     58 
     59 void CMy01_UDPServerDlg::DoDataExchange(CDataExchange* pDX)
     60 {
     61     CDialogEx::DoDataExchange(pDX);
     62     DDX_Text(pDX, IDC_EDIT1, peerPort);
     63     DDX_Text(pDX, IDC_EDIT2, localPort);
     64     DDX_Control(pDX, IDC_IPADDRESS1, addrCtrl);
     65     DDX_Text(pDX, IDC_EDIT3, sendBuf);
     66     DDX_Text(pDX, IDC_EDIT4, sendLen);
     67     DDX_Control(pDX, IDC_BUTTON1, startButton);
     68     DDX_Control(pDX, IDC_BUTTON2, stopButton);
     69 }
     70 
     71 BEGIN_MESSAGE_MAP(CMy01_UDPServerDlg, CDialogEx)
     72     ON_WM_SYSCOMMAND()
     73     ON_WM_PAINT()
     74     ON_WM_QUERYDRAGICON()
     75     ON_BN_CLICKED(IDC_BUTTON1, &CMy01_UDPServerDlg::OnBnClickedButton1)
     76     ON_WM_TIMER()
     77     ON_BN_CLICKED(IDC_BUTTON2, &CMy01_UDPServerDlg::OnBnClickedButton2)
     78 END_MESSAGE_MAP()
     79 
     80 
     81 // CMy01_UDPServerDlg 消息处理程序
     82 
     83 BOOL CMy01_UDPServerDlg::OnInitDialog()
     84 {
     85     CDialogEx::OnInitDialog();
     86 
     87     // 将“关于...”菜单项添加到系统菜单中。
     88 
     89     // IDM_ABOUTBOX 必须在系统命令范围内。
     90     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     91     ASSERT(IDM_ABOUTBOX < 0xF000);
     92 
     93     CMenu* pSysMenu = GetSystemMenu(FALSE);
     94     if (pSysMenu != NULL)
     95     {
     96         BOOL bNameValid;
     97         CString strAboutMenu;
     98         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
     99         ASSERT(bNameValid);
    100         if (!strAboutMenu.IsEmpty())
    101         {
    102             pSysMenu->AppendMenu(MF_SEPARATOR);
    103             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    104         }
    105     }
    106 
    107     // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    108     //  执行此操作
    109     SetIcon(m_hIcon, TRUE);            // 设置大图标
    110     SetIcon(m_hIcon, FALSE);        // 设置小图标
    111 
    112     // TODO:  在此添加额外的初始化代码
    113     peerPort = 8888;
    114     localPort = 9999;
    115     sendBuf = _T("准备发送数据");
    116     sendLen = 0;
    117     //把内容更新到对应的编辑区
    118     UpdateData(FALSE);
    119 
    120     addrCtrl.SetAddress(127, 0, 0, 1);
    121 
    122     stopButton.EnableWindow(FALSE);
    123 
    124     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    125 }
    126 
    127 void CMy01_UDPServerDlg::OnSysCommand(UINT nID, LPARAM lParam)
    128 {
    129     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    130     {
    131         CAboutDlg dlgAbout;
    132         dlgAbout.DoModal();
    133     }
    134     else
    135     {
    136         CDialogEx::OnSysCommand(nID, lParam);
    137     }
    138 }
    139 
    140 // 如果向对话框添加最小化按钮,则需要下面的代码
    141 //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    142 //  这将由框架自动完成。
    143 
    144 void CMy01_UDPServerDlg::OnPaint()
    145 {
    146     if (IsIconic())
    147     {
    148         CPaintDC dc(this); // 用于绘制的设备上下文
    149 
    150         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    151 
    152         // 使图标在工作区矩形中居中
    153         int cxIcon = GetSystemMetrics(SM_CXICON);
    154         int cyIcon = GetSystemMetrics(SM_CYICON);
    155         CRect rect;
    156         GetClientRect(&rect);
    157         int x = (rect.Width() - cxIcon + 1) / 2;
    158         int y = (rect.Height() - cyIcon + 1) / 2;
    159 
    160         // 绘制图标
    161         dc.DrawIcon(x, y, m_hIcon);
    162     }
    163     else
    164     {
    165         CDialogEx::OnPaint();
    166     }
    167 }
    168 
    169 //当用户拖动最小化窗口时系统调用此函数取得光标
    170 //显示。
    171 HCURSOR CMy01_UDPServerDlg::OnQueryDragIcon()
    172 {
    173     return static_cast<HCURSOR>(m_hIcon);
    174 }
    175 
    176 //发送按钮
    177 void CMy01_UDPServerDlg::OnBnClickedButton1()
    178 {
    179     // TODO:  在此添加控件通知处理程序代码
    180 
    181     //把编辑区的内容更新到对应的变量中
    182     UpdateData(TRUE);
    183 
    184     //创建UDP套接字
    185     if (socket.Create(localPort, SOCK_DGRAM) )
    186     {
    187         //启动定时器 处理 WM_TIMER消息
    188         SetTimer(1, 500, NULL);
    189 
    190         //开始按钮变灰
    191         startButton.EnableWindow(FALSE);
    192         //停止按钮恢复
    193         stopButton.EnableWindow(TRUE);
    194     }
    195     else //套接字创建失败
    196     {
    197         MessageBox(_T("创建套接字失败"));
    198     }
    199 
    200 }
    201 
    202 //定时器回调函数
    203 void CMy01_UDPServerDlg::OnTimer(UINT_PTR nIDEvent)
    204 {
    205     // TODO:  在此添加消息处理程序代码和/或调用默认值
    206 
    207     //组包,要发送的数据包
    208     char buf[32] = { 0 };
    209     static int i = 0;
    210     i++;
    211     sprintf_s(buf, sizeof(buf), "%010d", i);
    212 
    213     //获取对方的IP和端口
    214     UpdateData(TRUE); //获取编辑区的值
    215     BYTE a, b, c, d;
    216     addrCtrl.GetAddress(a, b, c, d);
    217     CString ip;
    218     ip.Format(_T("%d.%d.%d.%d"), a, b, c, d);
    219 
    220     //发送数据包
    221     int len = socket.SendTo(buf, strlen(buf), peerPort, ip);
    222     if (len > 0)
    223     {
    224         sendBuf = CString(buf); //char * -> CString
    225         sendLen += len;
    226 
    227         //把对应的值更新到编辑区
    228         UpdateData(FALSE);
    229     }
    230 
    231     CDialogEx::OnTimer(nIDEvent);
    232 }
    233 
    234 
    235 void CMy01_UDPServerDlg::OnBnClickedButton2()
    236 {
    237     // TODO:  在此添加控件通知处理程序代码
    238     sendBuf = _T("数据已经停止发送");
    239     UpdateData(FALSE);
    240 
    241     socket.Close(); //关闭套接字
    242     KillTimer(1); //关闭定时器
    243 
    244     startButton.EnableWindow(TRUE);
    245     stopButton.EnableWindow(FALSE);
    246 }
    View Code

    2.3  客户端通信步骤:

    a)在.h中创建CAsyncSocket类对象;

    b)创建套接字CAsyncSocket::Create();

    c)接受数据CAsyncSocket::ReceiveFrom();

    d)关闭套接字CAsyncSocket::Close();

    2.4 客户端MFC界面

    2.3  01_UDPClientDlg.h中添加类

     1 // 01_UDPClientDlg.h : 头文件
     2 //
     3 
     4 #pragma once
     5 #include "afxwin.h"
     6 
     7 
     8 // CMy01_UDPClientDlg 对话框
     9 class CMy01_UDPClientDlg : public CDialogEx
    10 {
    11 // 构造
    12 public:
    13     CMy01_UDPClientDlg(CWnd* pParent = NULL);    // 标准构造函数
    14 
    15 // 对话框数据
    16     enum { IDD = IDD_MY01_UDPCLIENT_DIALOG };
    17 
    18     protected:
    19     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    20 
    21 
    22 // 实现
    23 protected:
    24     HICON m_hIcon;
    25 
    26     // 生成的消息映射函数
    27     virtual BOOL OnInitDialog();
    28     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    29     afx_msg void OnPaint();
    30     afx_msg HCURSOR OnQueryDragIcon();
    31     DECLARE_MESSAGE_MAP()
    32 private:
    33     //自定义代码区
    34     UINT peerPort;
    35     UINT localPort;
    36     CString peerIP;
    37     CString recvBuf;
    38     int recvLen;
    39     CButton startButton;
    40     CButton stopButton;
    41     CAsyncSocket socket;
    42 public:
    43     afx_msg void OnBnClickedButton1();
    44     afx_msg void OnTimer(UINT_PTR nIDEvent);
    45     afx_msg void OnBnClickedButton2();
    46 };
    View Code

    2.4  01_UDPClientDlg.cpp中初始化,并创建、接受、关闭套接字

      1 // 01_UDPClientDlg.cpp : 实现文件
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "01_UDPClient.h"
      6 #include "01_UDPClientDlg.h"
      7 #include "afxdialogex.h"
      8 
      9 #ifdef _DEBUG
     10 #define new DEBUG_NEW
     11 #endif
     12 
     13 
     14 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
     15 
     16 class CAboutDlg : public CDialogEx
     17 {
     18 public:
     19     CAboutDlg();
     20 
     21 // 对话框数据
     22     enum { IDD = IDD_ABOUTBOX };
     23 
     24     protected:
     25     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
     26 
     27 // 实现
     28 protected:
     29     DECLARE_MESSAGE_MAP()
     30 };
     31 
     32 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
     33 {
     34 }
     35 
     36 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
     37 {
     38     CDialogEx::DoDataExchange(pDX);
     39 }
     40 
     41 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
     42 END_MESSAGE_MAP()
     43 
     44 
     45 // CMy01_UDPClientDlg 对话框
     46 
     47 
     48 
     49 CMy01_UDPClientDlg::CMy01_UDPClientDlg(CWnd* pParent /*=NULL*/)
     50     : CDialogEx(CMy01_UDPClientDlg::IDD, pParent)
     51     , peerPort(0)
     52     , localPort(0)
     53     , peerIP(_T(""))
     54     , recvBuf(_T(""))
     55     , recvLen(0)
     56 {
     57     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
     58 }
     59 
     60 void CMy01_UDPClientDlg::DoDataExchange(CDataExchange* pDX)
     61 {
     62     CDialogEx::DoDataExchange(pDX);
     63     DDX_Text(pDX, IDC_EDIT1, peerPort);
     64     DDX_Text(pDX, IDC_EDIT2, localPort);
     65     DDX_Text(pDX, IDC_EDIT3, peerIP);
     66     DDX_Text(pDX, IDC_EDIT4, recvBuf);
     67     DDX_Text(pDX, IDC_EDIT5, recvLen);
     68     DDX_Control(pDX, IDC_BUTTON1, startButton);
     69     DDX_Control(pDX, IDC_BUTTON2, stopButton);
     70 }
     71 
     72 BEGIN_MESSAGE_MAP(CMy01_UDPClientDlg, CDialogEx)
     73     ON_WM_SYSCOMMAND()
     74     ON_WM_PAINT()
     75     ON_WM_QUERYDRAGICON()
     76     ON_BN_CLICKED(IDC_BUTTON1, &CMy01_UDPClientDlg::OnBnClickedButton1)
     77     ON_WM_TIMER()
     78     ON_BN_CLICKED(IDC_BUTTON2, &CMy01_UDPClientDlg::OnBnClickedButton2)
     79 END_MESSAGE_MAP()
     80 
     81 
     82 // CMy01_UDPClientDlg 消息处理程序
     83 
     84 BOOL CMy01_UDPClientDlg::OnInitDialog()
     85 {
     86     CDialogEx::OnInitDialog();
     87 
     88     // 将“关于...”菜单项添加到系统菜单中。
     89 
     90     // IDM_ABOUTBOX 必须在系统命令范围内。
     91     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     92     ASSERT(IDM_ABOUTBOX < 0xF000);
     93 
     94     CMenu* pSysMenu = GetSystemMenu(FALSE);
     95     if (pSysMenu != NULL)
     96     {
     97         BOOL bNameValid;
     98         CString strAboutMenu;
     99         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
    100         ASSERT(bNameValid);
    101         if (!strAboutMenu.IsEmpty())
    102         {
    103             pSysMenu->AppendMenu(MF_SEPARATOR);
    104             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    105         }
    106     }
    107 
    108     // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    109     //  执行此操作
    110     SetIcon(m_hIcon, TRUE);            // 设置大图标
    111     SetIcon(m_hIcon, FALSE);        // 设置小图标
    112 
    113     // TODO:  在此添加额外的初始化代码
    114     localPort = 8888;
    115     peerPort = 9999;
    116     peerIP = _T("127.0.0.1");
    117 
    118     recvBuf = _T("准备接收数据……");
    119     recvLen = 0;
    120 
    121     //把值更新到对应的编辑区
    122     UpdateData(FALSE);
    123 
    124     stopButton.EnableWindow(FALSE);
    125 
    126     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    127 }
    128 
    129 void CMy01_UDPClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
    130 {
    131     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    132     {
    133         CAboutDlg dlgAbout;
    134         dlgAbout.DoModal();
    135     }
    136     else
    137     {
    138         CDialogEx::OnSysCommand(nID, lParam);
    139     }
    140 }
    141 
    142 // 如果向对话框添加最小化按钮,则需要下面的代码
    143 //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    144 //  这将由框架自动完成。
    145 
    146 void CMy01_UDPClientDlg::OnPaint()
    147 {
    148     if (IsIconic())
    149     {
    150         CPaintDC dc(this); // 用于绘制的设备上下文
    151 
    152         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    153 
    154         // 使图标在工作区矩形中居中
    155         int cxIcon = GetSystemMetrics(SM_CXICON);
    156         int cyIcon = GetSystemMetrics(SM_CYICON);
    157         CRect rect;
    158         GetClientRect(&rect);
    159         int x = (rect.Width() - cxIcon + 1) / 2;
    160         int y = (rect.Height() - cyIcon + 1) / 2;
    161 
    162         // 绘制图标
    163         dc.DrawIcon(x, y, m_hIcon);
    164     }
    165     else
    166     {
    167         CDialogEx::OnPaint();
    168     }
    169 }
    170 
    171 //当用户拖动最小化窗口时系统调用此函数取得光标
    172 //显示。
    173 HCURSOR CMy01_UDPClientDlg::OnQueryDragIcon()
    174 {
    175     return static_cast<HCURSOR>(m_hIcon);
    176 }
    177 
    178 void CMy01_UDPClientDlg::OnBnClickedButton1()
    179 {
    180     // TODO:  在此添加控件通知处理程序代码
    181 
    182     //把编辑区的内容更新到对应的变量中
    183     UpdateData(TRUE);
    184 
    185     //创建UDP套接字
    186     if (socket.Create(localPort, SOCK_DGRAM))
    187     {
    188         //启动定时器 处理 WM_TIMER消息
    189         SetTimer(1, 500, NULL);
    190 
    191         //开始按钮变灰
    192         startButton.EnableWindow(FALSE);
    193         //停止按钮恢复
    194         stopButton.EnableWindow(TRUE);
    195     }
    196     else //套接字创建失败
    197     {
    198         MessageBox(_T("创建套接字失败"));
    199     }
    200 }
    201 
    202 //定时器回调函数
    203 void CMy01_UDPClientDlg::OnTimer(UINT_PTR nIDEvent)
    204 {
    205     // TODO:  在此添加消息处理程序代码和/或调用默认值
    206 
    207     UpdateData(TRUE);
    208 
    209     char buf[32] = { 0 };
    210     int len = socket.ReceiveFrom(buf, sizeof(buf), peerIP, peerPort);
    211     if (len > 0)
    212     {
    213         recvBuf = CString(buf); // char * -> CString
    214         recvLen += len;
    215     }
    216     else
    217     {
    218         recvBuf = _T("停止接收数据");
    219         socket.Close();
    220         KillTimer(1);
    221         stopButton.EnableWindow(FALSE);
    222         startButton.EnableWindow(TRUE);
    223 
    224     }
    225 
    226     UpdateData(FALSE);
    227 
    228 
    229     CDialogEx::OnTimer(nIDEvent);
    230 }
    231 
    232 
    233 void CMy01_UDPClientDlg::OnBnClickedButton2()
    234 {
    235     // TODO:  在此添加控件通知处理程序代码
    236 
    237     recvBuf = _T("数据已经停止接收");
    238     UpdateData(FALSE);
    239 
    240     KillTimer(1); //关闭定时器
    241     socket.Close(); //关闭套接字
    242     
    243 
    244     startButton.EnableWindow(TRUE);
    245     stopButton.EnableWindow(FALSE);
    246 }
    View Code

    2.5 实现效果

  • 相关阅读:
    循环处理
    XMLHttpRequest 加载进度
    createjs 的 bitmapdata类
    console打印数组object具体内容
    html5 粒子组合成logo 的制作思路及方法
    createjs 更新
    css取消input、select默认样式(手机端)
    js获取url参数 兼容某些带#url
    Adobe Edge Animate CC 不再开发更新!
    《FLASH CC 2015 CANVAS 中文教程》——3、this关键字 入门
  • 原文地址:https://www.cnblogs.com/506941763lcj/p/11494386.html
Copyright © 2011-2022 走看看