CAsyncSocket编程 MFC
许多时候我们实现网络编程使用的是winsock api函数,虽然这些函数使用起来也很方便,很灵活,但是VC++的MFC类库中提供了CAsyncSocket这样一个套接字类,用它来实现socket编程会更方便。
1、服务器端 项目:CSockServer
Server端的编程与Client端的类似,下面主要介绍他的Listen及Accept函数
1. 建立一个CNewSocket类,重载CAsyncSocket类的OnReceive、OnSend函数,
如何进行信息的显示和发送可以参考Client程序。本例中采用将收到信息原封不动
发回的方法来实现Echo功能,代码如下
CNewSocket::OnReceive(int nErrorCOde){
m_nLength=Receive(m_szBuffer,sizeof(m_szBuffer),);
// 直接转发消息AsyncSelect(FD_WRITE);}CNewSocket::OnSend(int nErrorCode){ Send(m_szBuffer,m_nLength,0);}
2. 建立一个CMyServerSocket类,重载CAsyncSocket类的OnAccept函数代码如下
void CMyServerSocket::OnAccept(int nErrorCode){
//侦听到连接请求,调用Accept函数
CNewSocket* pSocket = new CNewSocket();
if (Accept(*pSocket)) {
pSocket- >AsyncSelect(FD_READ);
m_pSocket=pSocket;
} else
delete pSocket;}
在MyServerSocket.h中声明变量public::CNewSocket* m_pSocket;
3. 对话框添加一个侦听按钮,添加如下代码
void CCSockServerDlg::OnListen(){ if
(m_srvrSocket.m_hSocket==INVALID_SOCKET) {
BOOL bFlag=m_srvrSocket.Create
(UserPort,SOCK_STREAM,FD_ACCEPT);
if (!bFlag) { AfxMessageBox(“Socket Error!”);
M_srvrSocket.Close();
PostQuitMessage();
Return; } }
//“侦听”成功,等待连接请求if (!m_srvrSocket。Listen(1)){
int nErrorCode = m_srvrSocket.GetLastError();
if (nError!=WSAEWOULDBLOCK)
{
AfxMessageBox(“Socket Error!”);
M_srvrSocket.Close();
PostQuitMessage();
Return;
} }}
在CsockServerDlg.ccp中声明变量public: CMyServerSocket m_srvrSocket;
4. 目前程序只能实现Echo功能,将信息原封不动的转发,若能将Accept中由
CNewSocket* pSocket = new CNewSocket();
得到的Socket指针存入一个CList或一个数组中,便像Client端那样,对所有的连接进行读写控制。
2、客户端:
1. 创建项目CSockClient
2. 设计对话框
去掉OK和Cancle两个按钮,增加ID_Connect(连接)、ID_Send(发送)、ID_EXIT(关闭)按钮,添加ListBox控件IDC_LISTMSG和Edit控件IDC_EDITMSG,并按下表为为控件添加变量。
| IDC_EDITMSG | CEdit | m_MSGIDC_LISTMSG |
| CListBox | m_MSGS |
3. CAsyncSocket类用DoCallBack函数处理MFC消息,当一个网络事件发生时,DoCallBack函数按网络事件类型FD_READ、FD_WRITE、FD_ACCEPT、FD_CONNECT分别调用OnReceive、OnSend、OnAccept、OnConnect函数。由于MFC把这些函数定义为虚函数,所以要生成一个新的C++类,以重载这些函数。做法如下:
以public方式继承CAsyncSocket类,生成新类MySock类,为MySock类添加虚函数OnReceive、OnConnect、OnSend
4. 在MySock.h中添加以下代码:
public:
// 是否连接
BOOL m_bConnected;
// 消息长度
UINT m_nLength;
// 消息缓冲区
char m_szBuffer[];
5. 在MySock.cpp中重载各种函数
OnReceive、OnConnect、OnSend
6. 双击IDD_CSOCKCLIENT_DIALOG对话框中的连接按钮,添加以下代码
CCSockClientDlg::OnConnect() {
m_clientSocket.ShutDown();
m_clientSocket.m_hSocket=INVALID_SOCKET;
m_clientSocket.m_bConnected=FALSE;
CAddrDlg m_Dlg; //默认端口1088m_Dlg.m_Port=1088;
if (m_Dlg.DoModal()==IDOK && !m_Dlg.m_Addr.IsEmpty()) {
memcpy(m_szServerAdr,m_Dlg.m_Addr,sizeof(m_szServerAdr));
m_szPort=m_Dlg.m_Port; //建立计时器,每1秒尝试连接一次,直到连上或TryCount>10SetTimer(1,1000,NULL);
TryCount=; }}
7. 添加Windows消息WM_TIMER响应函数
OnTimer void CCSockClientDlg::OnTimer(UINT nIDEvent) {
if (m_clientSocket.m_hSocket==INVALID_SOCKET) {
BOOL bFlag=m_clientSocket.Create(,SOCK_STREAM,FD_CONNECT);
if(!bFlag) { AfxMessageBox("Socket Error!");
m_clientSocket.Close();
PostQuitMessage();
return;
} }
m_clientSocket.Connect(m_szServerAdr,m_szPort);
TryCount++;
if (TryCount >= || m_clientSocket.m_bConnected) {
KillTimer();
if (TryCount >=) AfxMessageBox("Connect Failed!");
return; }
CDialog::OnTimer(nIDEvent);}
8. 双击IDD_CSOCKCLIENT_DIALOG对话框中的发送按钮,添加以下代码
void CCSockClientDlg::OnSend() {
if (m_clientSocket.m_bConnected)
{m_clientSocket.m_nLength=m_MSG.GetWindowText(m_clientSocket.m_szBuffer, sizeof(m_clientSocket.m_szBuffer));
m_clientSocket.AsyncSelect(FD_WRITE);
m_MSG.SetWindowText(""); }}
9. 双击IDD_CSOCKCLIENT_DIALOG对话框中的关闭按钮,添加以下代码
CCSockClientDlg::OnExit() {
//关闭Socketm_clientSocket.ShutDown(2); //关闭对话框EndDialog(0); }
3、总结
CAsyncSocket类为我们使用Socket提供了极大方便。建立Socket的WSAStartup过程和bind过程被简化成为Create过程,
IP地址类型转换、主机名和IP地址转换的过程中许多复杂的变量类型都被简化成字符串和整数操作,特别是CAsyncSocket
类的异步特点,完全可以替代繁琐的线程操作。MFC提供了大量的类库,我们若能灵活的使用他们,便会大大提高编程的效
4、我的疑问
此文为转载,自己还没有实际的实验过,所以还没有什么疑问,
转载自:MFC网络编程学习
CAsyncSocket编程 MFC的更多相关文章
- CSocket类网络编程 MFC
Visual C++的MFC提供了CSocket类用来实现网络通信. 下面介绍VC++在Windows 95中实现Socket的 CSocket 类相关成员函数(这些成员函数实际上是从CAsyncSo ...
- Python -- Gui编程 -- MFC的使用
1.消息框 mfcDialog.py import win32ui import win32con from pywin.mfc import dialog class MyDialog(dialog ...
- 转:MFC网络编程学习
要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等. 2.在实际Windows网络通信软件开发中,异步非阻 ...
- 《转》MFC网络编程学习
原地址:http://www.cnblogs.com/renyuan/archive/2013/06/04/3117006.html要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(S ...
- MFC- socket 编程
一.CAsyncSocket类 CAsyncSocket属于异步非阻塞类. CAsyncSocket类采用了windows socket中的WSAAsyncSelect模型.CAsyncSocket ...
- VC++/MFC(VC6)开发技术精品学习资料下载汇总
工欲善其事,必先利其器,VC开发MFC Windows程序,Visual C++或Visual Studio是必须的,恩,这里都给你总结好了,拿去吧:VC/MFC开发必备Visual C++.Visu ...
- MFC的初始化过程和消息映射技术
1.删除#include <windows.h>--win32中的-(使用win32工程编程mfc必须删除) 添加#include <afxwin.h> -- mfc中的- 2 ...
- 套接字编程(VC_Win32)
简介(源于维基) Berkeley套接字(也作BSD套接字应用程序接口)刚开始是4.2BSD Unix操作系统(于1983发布)的一套应用程序接口.然而,由于AT&T的专利保护着UNIX,所以 ...
- MFC,ADO方式实现数据库操作
参考: MSDN数据访问编程 (MFC/ATL): https://msdn.microsoft.com/zh-cn/library/kd4ck1tt.aspx?f=255&MSPPError ...
随机推荐
- 位图算法 C语言
#include <stdio.h> void set_bit(void *base, unsigned long n) { unsigned long *m = (unsigned lo ...
- 堆叠相冊效果,兼容pc和移动端
在手机端,堆叠效果的相冊是比較常见的一种图片展示方式,每一个人的思路可能会有一些不同,实现的方法不同. 本篇博客主要是分享下我的实现方法.欢迎大家提出建议,指出我的不足,先3Q啦~ 先看一下终于的效果 ...
- python之模块csv之CSV文件的写入(基本结构)
# -*- coding: utf-8 -*- #python 27 #xiaodeng #CSV文件的写入(基本结构) import csv #csv文件,是一种常用的文本格式,用以存储表格数据,很 ...
- IP欺骗:要虚拟很多IP的情况:在一台机上虚拟的IP跨网段的处理,可通过在服务器端添加路由来实现
要虚拟很多IP的情况:在一台机上虚拟的IP跨网段的处理,可通过在服务器端添加路由来实现. 例: [服务器] IP:192.168.0.1 [测试机] IP:192.168.0.2 测试机上添加的虚拟 ...
- Linux下FTP命令的使用方法
FTP> ? 显示 ftp 命令说明.? 与 help 相同. 格式:? [command] 说明:[command]指定需要帮助的命令名称.如果没有指定 command,ftp 将显示全部命令 ...
- IOS开发之瀑布流照片墙实现
想必大家已经对互联网传统的照片布局方式司空见惯了,这种行列分明的布局虽然对用户来说简洁明了,但是长久的使用难免会产生审美疲劳.现在网上流行一种叫做“瀑布流”的照片布局样式,这种行与列参差不齐的状态着实 ...
- js常用点
<span onClick="onDetail(this.id,'edit');" style="cursor: hand;color:black;" ...
- POJ 3691 DNA repair (DP+AC自动机)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4815 Accepted: 2237 Descri ...
- Android应用的自动升级、更新模块的实现
我们看到很多Android应用都具有自动更新功能,用户一键就可以完成软件的升级更新.得益于Android系统的软件包管理和安装机制,这一功能实现起来相当简单,下面我们就来实践一下.首先给出界面效果: ...
- MVC中JSON字符长度超出限制
本文导读:在MVC中通过JsonResult返回JSON字符串时,如果字符串长度过长,会抛出使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错,字符串的长度超过了为 ...