2022年网络编程 .pdf
《2022年网络编程 .pdf》由会员分享,可在线阅读,更多相关《2022年网络编程 .pdf(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、MFC socket 编程2007-10-29 13:35 福州大学王骏- 随着计算机网络化的深入,计算机网络编程在程序设计的过程中变得日益重要。由于 C+ 语言对底层操作的优越性,许多文章都曾经介绍过用VC+ 进行Socket 编程的方法。但由于都是直接利用动态连接库wsock32.dll进行操作,实现比较繁琐。其实, VC+ 的 MFC 类库中提供了 CAsyncSocket这样一个套接字类,用他来实现 Socket 编程,是非常方便的。- 本文将用一个 Echo例程来介绍 CAsyncSocket类的用法。- 一 客户端- 1 创建一个 Dialog Based项目: CSockClie
2、nt 。在 Socket 项上面打上勾- 2 设计对话框- 去掉 Ok和 Cancle 两个按钮,增加 ID_Connect(连接)、ID_Send (发送)、ID_Exit(关闭) 按钮, 增加 ListBox 控件 IDC_LISTMSG 和 Edit 控件 IDC_EDITMSG,并按下表在 ClassWizard 中为 CCSockClientDlg 类添加变量。Control ID Type Member IDC_EDITMSG CEdit m_MSG IDC_LISTMSG ClistBox m_MSGS - 3 CAsyncSocket 类用 DoCallBack 函数处理 MF
3、C 消息,当一个网络事件发生时, DoCallBack 函数按网络事件类型:FD_READ、FD_WRITE 、FD_ACCEPT、FD_CONNECT分别调用 OnReceive、 OnSend 、 OnAccept、OnConnect函数。由于 MFC把这些事件处理函数定义为虚函数,所以要生成一个新的C+ 类,以重载这些函数,做法如下:- 以 Public方式继承 CAsyncSocket 类,生成新类 MySock ;- 为 MySock类添加虚函数 OnReceive、OnConnect 、OnSend - 4 在 MySock.ccp 中添加以下代码#include SockClie
4、nt.h #include SockClientDlg.h - 5 在 MySock.h中添加以下代码名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 16 页 - - - - - - - - - public: BOOL m_bConnected; /是否连接 UINT m_nLength; /消息长度 char m_szBuffer4096; /消息缓冲区- 6 在 MySock.ccp 中重载各函数MySock:MySock() m_nLength=0; memset
5、(m_szBuffer,0,sizeof(m_szBuffer); m_bConnected=FALSE; MySock:MySock() / 关闭套接字if(m_hSocket!=INVALID_SOCKET) Close(); void MySock:OnReceive(int nErrorCode) m_nLength=Receive(m_szBuffer,sizeof(m_szBuffer),0); / 下面两行代码用来获取对话框指针CCSockClientApp* pApp=(CCSockClientApp*)AfxGetApp(); CCSockClientDlg* pDlg=(C
6、CSockClientDlg*)pApp- m_pMainWnd; pDlg- m_MSGS.InsertString(0,m_szBuffer); memset(m_szBuffer,0,sizeof(m_szBuffer); CAsyncSocket:OnReceive(nErrorCode); void MySock:OnSend(int nErrorCode) Send(m_szBuffer,m_nLength,0); m_nLength=0; memset(m_szBuffer,0,sizeof(m_szBuffer); / 继续提请一个“读”的网络事件,接收Server 消息Asy
7、ncSelect(FD_READ); CAsyncSocket:OnSend(nErrorCode); void MySock:OnConnect(int nErrorCode) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 16 页 - - - - - - - - - if (nErrorCode=0) m_bConnected=TRUE; CCSockClientApp* pApp=(CCSockClientApp*)AfxGetApp(); CCSockClien
8、tDlg* pDlg=(CCSockClientDlg*)pApp- m_pMainWnd; memcpy(m_szBuffer,Connected to ,13); strncat(m_szBuffer,pDlg- m_szServerAdr, sizeof(pDlg- m_szServerAdr); pDlg- m_MSGS.InsertString(0,m_szBuffer); AsyncSelect(FD_READ); /提请一个“读”的网络事件,准备接收 CAsyncSocket:OnConnect(nErrorCode); - 7 新建对话框 IDD_Addr,用来输入 IP 地址
9、和 Port ;生成新类 CAddrDlg。增加两个 Edit 控件:IDC_Addr、IDC_Port 按下表在 ClassWizard 中为 CAddrDlg类添加变量。Control ID Type Member IDC_Addr CString m_Addr IDC_Port Int m_Port - 8 在 CSockClientDlg.ccp中添加代码#include AddrDlg.h protected: int TryCount; MySock m_clientSocket; UINT m_szPort; public: char m_szServerAdr256; - 9
10、双击 IDD_CSOCKCLIENT_DIALOG对话框中的“连接”按钮,添加以下代码void CCSockClientDlg:OnConnect() m_clientSocket.ShutDown(2); m_clientSocket.m_hSocket=INVALID_SOCKET; m_clientSocket.m_bConnected=FALSE; CAddrDlg m_Dlg; / 默认端口 1088 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 16 页 -
11、 - - - - - - - - m_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 秒尝试连接一次,直到连上或TryCount10 SetTimer(1,1000,NULL); TryCount=0; - 10 添加 Windows消息 WM_TIMER响应函数 OnTimer void CCSockClientDlg:OnT
12、imer(UINT nIDEvent) if (m_clientSocket.m_hSocket=INVALID_SOCKET) BOOL bFlag=m_clientSocket.Create(0,SOCK_STREAM,FD_CONNECT); if(!bFlag) AfxMessageBox(Socket Error!); m_clientSocket.Close(); PostQuitMessage(0); return; m_clientSocket.Connect(m_szServerAdr,m_szPort); TryCount+; if (TryCount =10 | m_cl
13、ientSocket.m_bConnected) KillTimer(1); if (TryCount =10) AfxMessageBox(Connect Failed!); return; CDialog:OnTimer(nIDEvent); - 11 双击 IDD_CSOCKCLIENT_DIALOG对话框中的“发送”按钮,添加以下代码void CCSockClientDlg:OnSend() if (m_clientSocket.m_bConnected) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 -
14、 - - - - - - 第 4 页,共 16 页 - - - - - - - - - m_clientSocket.m_nLength=m_MSG.GetWindowText (m_clientSocket.m_szBuffer, sizeof(m_clientSocket.m_szBuffer); m_clientSocket.AsyncSelect(FD_WRITE); m_MSG.SetWindowText(); - 12 双击 IDD_CSOCKCLIENT_DIALOG对话框中的“关闭”按钮,添加以下代码void CCSockClientDlg:OnExit() / 关闭 Sock
15、et m_clientSocket.ShutDown(2); / 关闭对话框EndDialog(0); - 12运行此项目,连接时输入主机名或IP 均可, CAsyncSocket 类会自动处理。- 二 服务端- Server 端的编程与 Client端的类似, 下面主要介绍他的Listen及 Accept 函数- 1 建立一个 CNewSocket类,重载 CAsyncSocket 类的 OnReceive、 OnSend函数,如何进行信息的显示和发送可以参考Client程序。本例中采用将收到信息原封不动发回的方法来实现Echo功能,代码如下CNewSocket :OnReceive(int
16、 nErrorCOde ) m_nLength=Receive(m_szBuffer ,sizeof (m_szBuffer ),0);/ 直接转发消息AsyncSelect (FD_WRITE); CNewSocket :OnSend (int nErrorCode) Send(m_szBuffer ,m_nLength,0); - 2 建立一个 CMyServerSocket 类,重载 CAsyncSocket类的 OnAccept 函数代码如下名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - -
17、 - - 第 5 页,共 16 页 - - - - - - - - - - 在 MyServerSocket.h 中声明变量public::CNewSocket* m_pSocket ;void CMyServerSocket :OnAccept(int nErrorCode) / 侦听到连接请求,调用Accept 函数CNewSocket* pSocket = new CNewSocket ();if (Accept(*pSocket ) pSocket- AsyncSelect(FD_READ);m_pSocket=pSocket; else delete pSocket; - 3 为对话
18、框添加一个“侦听”按钮,添加如下代码- 在 CsockServerDlg.ccp中声明变量public :CMyServerSocket m_srvrSocket; 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(); PostQuit
19、Message(0); Return; / “侦听”成功,等待连接请求if (!m_srvrSocket 。Listen (1) int nErrorCode = m_srvrSocket.GetLastError(); if (nError !=WSAEWOULDBLOCK) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 16 页 - - - - - - - - - AfxMessageBox(“Socket Error!”); M_srvrSocket.Close(
20、); PostQuitMessage(0); Return; - 4 目前程序只能实现Echo功能,将信息原封不动的转发, 若能将 Accept 中由CNewSocket* pSocket = new CNewSocket ();得到的 Socket 指针存入一个CList 或一个数组中,便像Client端那样,对所有的连接进行读写控制。- 三 总结- CAsyncSocket类为我们使用 Socket 提供了极大方便。建立 Socket 的 WSAStartup过程和 bind 过程被简化成为 Create 过程,IP 地址类型转换、主机名和IP 地址转换的过程中许多复杂的变量类型都被简化成
21、字符串和整数操作,特别是CAsyncSocket类的异步特点, 完全可以替代繁琐的线程操作。MFC 提供了大量的类库,我们若能灵活的使用他们,便会大大提高编程的效率。一、TCP/IP 体系结构与特点1、TCP/IP 体系结构TCP/IP 协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而 IP 则是提供网络层服务。 TCP/IP 包括以下协议: (结构如图1.1 )名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 16 页 - - - - - -
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年网络编程 2022 网络 编程
限制150内