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 ...
随机推荐
- js 垃圾回收机制与内存管理
1.原理 js按照固定的时间间隔找到不在继续使用的变量,释放其占用的内存. 2.实现方式 (1)标记清除 垃圾收集器给存储在内存上的所有变量都加上标记: 之后,去掉环境中的变量以及被环境引用变量的标记 ...
- 剑指offer(2) - 二维数组中的查找
题目: 在一个二维数组中.每一行都依照从左到右递增的顺序排序,每一列都依照从上往下递增的顺序排序.请写一个函数,输入一个二维数组和一个整数,推断数组中是否含有该整数. 比如以下的二维数组就是每行.每列 ...
- poi读取execl的日期
当execl中的列为日期格式时,后台读取到是一个数字,通过如下代码可以直接读取并转换到Date类型 HSSFDateUtil.getJavaDate(cell.getNumericCellValue( ...
- java开发工具之myeclipse调优
-vmargs -Xms512m //堆的最小值-Xmx512m //堆的最大值(两者设置相同,避免运行时的自动扩张)-XX:PermSize=256m //永久代的最小值 -XX:MaxPermSi ...
- QQ概念版(WPF制作)
984 QQ概念版 编辑 QQ 概念版是腾讯首款NUI(自然用户交互)产品,全面实现了多点触摸操作.是腾讯利用微软最新一代的客户端展现层技术--WPF,打造的IM产品. 中文名 QQ 概念版 游戏 ...
- 着重protected、default区别
public是所有,在哪都可以访问private是私有,仅在自己类里面可以访问protected是自己包里面可以访问,如果有不同包的类想调用它们,那么这个类必须是定义它们的类的子类.default也是 ...
- Tomcat路径下目录的介绍
本文转自:http://blog.csdn.net/u013132035/article/details/54949593 下图是TOMCAT的路径下目录的截图. 目录有:backup. ...
- HTML:关于HTML的Doctype和严格模式与混杂模式
DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档. Doctype可声明三种DTD类型,分别表示严格 ...
- SSL原理
http://blog.csdn.net/terryzero/article/details/5921791SSL的原理以前一直很模糊,看了下面这篇文章后清楚了许多,为了方便以后的回顾,所以转载下 R ...
- Cookies揭秘 [Asp.Net, Javascript]
一,前言 Cookies想必所有人都了解, 但是未必所有人都精通.本文讲解了Cookies的各方面知识, 并且提出来了最佳实践.这是笔者在日常工作中的积累和沉淀. 二,基础知识 1.什么是Cookie ...