MFC 通信编程 -----下篇

继上一篇有关服务器的网络编程,这里继续探讨客户端如何发出连接服务器的请求,如何与服务器进行数据传输,如何与其他客户端交换数据,最后如何断开与服务器之间的连接。

关键技术就是TCP/IP协议,socket默认使用的是非阻塞式异步传输通讯方式,对应MFC中的CSoket类,采用的是面向连接的TCP协议而不是UDP协议。

工具/原料

  • Visual Studio 2010/2013

方法/步骤

  1. 1

    创建一个项目,与服务器端类似,别忘了选择“windows套接字”。创建好以后设计对话框界面。2个按钮,1个用来连接或者断开服务器,另一个用来发送数据;2个编辑框,一个用来显示接收到的数据,另一个用来输入需要发送的数据。

  2. 2

    编辑控件的属性,通过类向导添加相应的变量,双击按钮添加按钮按下处理事件。

  3. 3

    添加客户端类CClientSocket,通过类向导添加OnReceive函数。

  4. 4

    修改客户端类的头文件:

    /********************ClientSocket.h*********************/

    #pragma once

    class CClientSocket : public CSocket

    {

    public:

             CClientSocket();

             virtual ~CClientSocket();

             virtual void OnReceive(int nErrorCode);           

    // 重写接收函数,通过类向导生成

             BOOL SendMSG(LPSTR lpBuff, int nlen);           

    // 发送函数,用于发送数据给服务器

    };

    MFC/Socket网络编程:[2]客户端 
  5. 5

    修改客户端类的源文件:

    /********************ClientSocket.cpp*********************/

    #include "stdafx.h"

    #include "PhoneClient.h"

    #include "ClientSocket.h"

    #include "PhoneClientDlg.h"

     

    CClientSocket::CClientSocket(){}

    CClientSocket::~CClientSocket(){}

     

    void CClientSocket::OnReceive(int nErrorCode)

    {

             // TODO:  在此添加专用代码和/或调用基类

             char* pData = NULL;

             pData = new char[1024];

             memset(pData, 0, sizeof(char)* 1024);

             UCHAR leng = 0;

             CString str;

             leng = Receive(pData, 1024, 0);

             str = pData;

    // 在编辑框中显示接收到的数据

             ((CPhoneClientDlg*)theApp.GetMainWnd())->SetDlgItemTextW(IDC_DataReceive, str);

             delete pData;

             pData = NULL;

             CSocket::OnReceive(nErrorCode);

    }

     

    BOOL CClientSocket::SendMSG(LPSTR lpBuff, int nlen)

    {

             //生成协议头

             if (Send(lpBuff, nlen) == SOCKET_ERROR)

             {

                       AfxMessageBox(_T("发送错误!"));

                       return FALSE;

             }

             return  TRUE;

    }

    说明:当客户端接收到服务器端发的数据时会响应接收函数OnReceive,这里只是简单的将获取的信息显示在编辑框中。SendMSG函数用于向服务器发送消息,函数会在主对话框类中调用。

    MFC/Socket网络编程:[2]客户端 
  6. 6

    修改对话框类的头文件,添加相关函数声明以及必要的变量定义:

    bool m_connect;

    CClientSocket* pSock;                        // 客户端套接字指针对象

    BOOL WChar2MByte(LPCWSTR lpSrc, LPSTR lpDest, int nlen);      

    //字符转换函数

    public:

    virtual BOOL PreTranslateMessage(MSG* pMsg); 

    //防止按下enter、esc时退出程序

    MFC/Socket网络编程:[2]客户端 
  7. 7

    在对话框类的源文件中编写所有声明的函数,实现各项函数的功能。

    1、 连接服务器的按钮事件处理函数

    void CPhoneClientDlg::OnBnClickedConnect()

    {

             if (m_connect)                             // 如果已经连接,则断开服务器

             {

                       m_connect = false;

                       pSock->Close();

                       delete pSock;

                       pSock = NULL;

                       m_ConPC.SetWindowTextW(_T("连接服务器"));

                       UpdateData(false);

                       return;

             }

             else                                                // 未连接,则连接服务器

             {

                       pSock = new CClientSocket();

                       if (!pSock->Create())         //创建套接字

                       {

                                AfxMessageBox(_T("创建套接字失败!"));

                                return;

                       }

             }

             if (!pSock->Connect(_T("127.0.0.1"), port))    //连接服务器

             {

                       AfxMessageBox(_T("连接服务器失败!"));

                       return;

             }

             else

             {

                       m_connect = true;

                       m_ConPC.SetWindowTextW(_T("断开服务器"));

                       UpdateData(false);

             }

    }

    说明:本函数通过Create和Connect与服务器建立连接。由于在本机上测试,所以IP为127.0.0.1,实际应用时可以添加一个控件用于输入服务器的IP。端口号必须与服务器的一致,这里的port是一个常量:

    #define port 8000

    MFC/Socket网络编程:[2]客户端 
  8. 8

    2、 发送按钮的事件处理函数

    void CPhoneClientDlg::OnBnClickedSend()

    {

             // TODO:  在此添加控件通知处理程序代码

             if (!m_connect)return;                               //未连接服务器则不执行

             UpdateData(true);                                     //获取界面数据

             if (m_DataSend != "")                                           

             {

                       char* pBuff = new char[m_DataSend.GetLength() * 2];

                       memset(pBuff, 0, m_DataSend.GetLength() * 2);

                       WChar2MByte(m_DataSend.GetBuffer(0), pBuff, m_DataSend.GetLength() * 2);

                       pSock->SendMSG(pBuff, m_DataSend.GetLength() * 2);

             }

    }

    说明:这里的SendMSG函数与服务器端的不一致,函数实体在CClientSocket类中以实现。WChar2MByte字符转换函数与服务器端的一致,在这不再赘述。

    MFC/Socket网络编程:[2]客户端 
  9. 9

    对话框的主要函数就是以上2个,一个用于连接和断开服务器,另一个用于发送数据。至于虚函数PreTeanslateMessage,其处理方法与服务器中介绍的一致。将服务器与客户端都编写好以后,就可以测试通讯效果,可以同时打开多个客户端,看看服务器如何处理。

    MFC/Socket网络编程:[2]客户端 
    MFC/Socket网络编程:[2]客户端 
    END

注意事项

  • 这篇经验需要参考上一篇关于服务器端编程的经验
  • 服务器端与客户端通过socket实现网络通讯
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值