MFC的网络编程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

MFC的网络编程今天来八一八,MFC的SOCKET编程,利用CSocket实现一个基于TCP实现一个QQ聊天程序。你会发现,MFC要比WIN32简单的多。但是如果你不理解具体APIsocket基础知识,你可能会觉得有一点费解。所以在开始之前我还是请大家先看看在应用程序开始的时候,我们先应该初始话winSock库,所以便会用到下面的一个函数。[cpp]viewplaincopy1.BOOLAfxSocketInit(WSADATA*lpwsaData=NULL);//用来初始化Socket,用WSAStartup();来初始化,在应用程序结束时他会自动调用WSACleanup()我们在开始编程之前,应该调用这个函数,对Socket进行初始化。如果初始化成功返回非0,否则返回0.可能人会问,这个函数加载的是那个版本的Socket库呢?通过查看底层代码,我们发现,他加载的是1.1版本的Socket注意:这个函数只能在你自己应用程序的CXXWinApp::InitInstance中初始化.在初始化前还要记得加入头文件Afxsock.h我服务器端程序为NetChatServer所以我在的CNetChatServerApp::InitInstance()中加入/////////////////////////////////////////////////////////////////////////////////////////////////////CNetChatServerApp::InitInstance()///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[cpp]viewplaincopy1.if(!AfxSocketInit())2.{3.AfxMessageBox(_T(Socket库初始化出错!));4.returnfalse;5.}m_iSocket是一个CServerSocket*的指针,CServerSocket类是一个我们自己的类我会在后面给出相应代码,他继承于CSocket类。[cpp]viewplaincopy1.m_iSocket=newCServerSocket();//1.动态创建一个服务器Socket对象。2.if(!m_iSocket)3.{4.AfxMessageBox(_T(动态创建服务器套接字出错!));5.returnfalse;6.}接着创建套接字[cpp]viewplaincopy1.if(!m_iSocket-Create(8989))2.{3.AfxMessageBox(_T(创建套接字错误!));4.m_iSocket-Close();5.returnfalse;6.}其中8989是指定的端口号,但是要注意在保存我们指定的8989端口前,这个端口是空闲的没有被其他进程所占用,那怎么查看端口是否被其他进程占用呢?首先打开cmd键入netstat-aon你会看到所有的TCP/UDP信息,但是由于太多了不好查看,所以。我们再在最下面tasklist|find“8989”现在我们看到我们没有找到任何和8989端口相关的东西,所以说明8989端口没有被占用。创建了套接字以后按照win32的步骤我们就应该对bind端口。但是MFC不这样,应为MFC的Create内部已经调用了bind,如下是MFC的底层代码[cpp]viewplaincopy1.BOOLCAsyncSocket::Create(UINTnSocketPort,intnSocketType,longlEvent,LPCTSTRlpszSocketAddress)2.{3.if(Socket(nSocketType,lEvent))4.{5.if(Bind(nSocketPort,lpszSocketAddress))//调用了bind6.returnTRUE;7.intnResult=GetLastError();8.Close();9.WSASetLastError(nResult);10.}11.returnFALSE;12.}所以我们不用在调用bind了,直接对套接字进行监听[cpp]viewplaincopy1.if(!m_iSocket-Listen())2.{3.AfxMessageBox(_T(监听失败!));4.m_iSocket-Close();5.returnfalse;6.}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////然后重载ExitInstance,退出时对进行清理[cpp]viewplaincopy1.intCNetChatServerApp::ExitInstance()2.{3.if(m_iSocket)4.{5.deletem_iSocket;6.m_iSocket=NULL;7.}8.returnCWinApp::ExitInstance();9.}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////下面来看下CServerSocket的具体实现[cpp]viewplaincopy1.#pragmaonce2.3.#includeClientSocket.h4.5.classCServerSocket:publicCSocket6.{7.public:8.CServerSocket();9.virtual~CServerSocket();10.public:11.CPtrListm_listSockets;//用来保存服务器与所有客户端连接成功后的ClientSocket12.13.14.public:15.virtualvoidOnAccept(intnErrorCode);16.};[cpp]viewplaincopy1.#includestdafx.h2.#includeNetChatServer.h3.#includeServerSocket.h4.5.CServerSocket::CServerSocket()6.{7.8.}9.10.CServerSocket::~CServerSocket()11.{12.13.}14.15.voidCServerSocket::OnAccept(intnErrorCode)16.{17.//接受到一个连接请求18.CClientSocket*theClientSock(0);19.theClientSock=newCClientSocket(&m_listSockets);20.if(!theClientSock)21.{22.AfxMessageBox(_T(内存不足,客户连接服务器失败!));23.return;24.}25.Accept(*theClientSock);26.//加入list中便于管理27.m_listSockets.AddTail(theClientSock);28.CSocket::OnAccept(nErrorCode);29.}我们可以看到在CServerSocket中又出现了一个CClientSocket的类,这个类和CServerSocket一样,也是派生于CSocket类,但是专门用于客户端的Socket。在这里必须重载OnAccept(intnErrorCode)函数,这样CServerSocket才能接收到客户端的请求,并且必须在OnAccept中调用Accept()函数对连接请求进行响应。在OnAccept()我们用一个List将ClientSocket指针保存,以便以后调用访问。///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////接着我们再来看看CClientSocket类[cpp]viewplaincopy1.#pragmaonce2.3.#includestdafx.h4./////////////////////////////////////////////////5.///说明,该类用于和客户端建立通信的Socket6./////////////////////////////////////////////////7.8.classCClientSocket:publicCSocket9.{10.public:11.CClientSocket(CPtrList*pList);12.virtual~CClientSocket();13.public:14.CPtrList*m_pList;//保存服务器ClientSocket中List的东西,这个是中CServerSocket中传过来的15.CStringm_strName;//连接名称16.public:17.virtualvoidOnClose(intnErrorCode);18.virtualvoidOnReceive(intnErrorCode);19.voidOnLogoIN(char*buff,intnlen);//处理登录消息20.voidOnMSGTranslate(char*buff,intnlen);//转发消息给其他聊天群21.CStringUpdateServerLog();//服务器端更新、记录日志22.voidUpdateAllUser(CStringstrUserInfo);//更新服务器端的在线人员列表23.private:24.BOOLWChar2MByte(LPCWSTRsrcBuff,LPSTRdestBuff,intnlen);//多字节的转换25.};可以看到我们重载了OnClose()、OnReceive()函数,这样当套接字关闭、有数据到达时,就会自动调用这两个函数,我们便可以在这两个函数中响应、处理事件。由于本人使用的是VS2010,并且采用的Unicode编码

1 / 21
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功