设为首页 加入收藏

TOP

11.2.3 封装CData类
2013-10-07 13:03:05 来源: 作者: 【 】 浏览:66
Tags:11.2.3 封装 CData

11.2.3  封装CData类

在11.2.2节中,分别向用户介绍了服务器端和客户端的各个功能实现方法。为了让用户深入了解C++(www.cppentry.com)面向对象编程(www.cppentry.com)的方法,在本节中,将各个功能函数封装在CData类中。使用时,直接生成CData类实例对象,通过该对象调用相关的功能函数。

1.定义CData类

首先,用户需要定义CData类头文件Data.h。代码如下:

  1. class CData  
  2. {  
  3. public:  
  4.     CData();                                    //构造函数  
  5.    void bind();                             //服
    务器绑定套接字函数  
  6.    void sevsend(SOCKET&,char*,int,int);     //服务器发送函数  
  7.    void sevrecv(SOCKET&,char*,int,int);     //服务器接收函数  
  8.    void connect();                          //客户端连接函数  
  9.    void send(SOCKET&,char*,int,int);        //客户端发送函数  
  10.    void recv(SOCKET&,char*,int,int);        //客户端接收函数  
  11. ~CData();  
  12.    }; 

然后,在定义文件Data.cpp中,实现各个功能函数的具体方法。代码如下:

  1. #include "Data.h"  
  2. #include "iostream.h"  
  3. CData::CData()                                  //构造函数  
  4. {  
  5.    }  
  6. void CData::bind()                              //服务
    器绑定套接字函数  
  7. {  
  8.   WSADATA data;                                 //定义结构体变量  
  9.    CString name;                                //定义主机名字符串  
  10.     DWORD ss=MAKEWORD(2,0);                     //指定套接字版本  
  11.    ::WSAStartup(ss,&data);                      //初始化套接字库  
  12.    s=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  13.                                                 //创建套接字  
  14.    sockaddr_in addr;                            //定义地址结构变量  
  15. ::gethostname((char*)&name,(int)sizeof(name));  //获得主机名字  
  16.     hostent *p=::gethostbyname((char*)&name);   //从主
    机名获取主机地址  
  17.      in_addr *a=(in_addr*)*p->h_addr_list;      //获得本机IP地址  
  18.      CString str14=::inet_ntoa(a[0]);           //转换字符串IP地址  
  19.    addr.sin_family=AF_INET;                     //填充地址结构  
  20.     addr.sin_port=htons(80);                    //指定监听端口为80  
  21.     addr.sin_addr.S_un.S_addr=inet_addr(str14);//指定主机IP地址  
  22.     ::bind(s,(sockaddr*)&addr,sizeof(addr));    //将
    本地信息绑定到套接字  
  23.     ::listen(s,5);                              //监听  
  24. WSAAsyncSelect(s,this->m_hWnd,WM_SOCK,FD_ACCEPT|FD_READ);  
  25.                                                 //将套
    接字设置为异步模式  
  26. }  
  27. void CData::sevsend(SOCKET s,char* buff,int len,int flags)  
  28.                                                 //自定
    服务器发送函数  
  29. {  
  30.             send(s,buff,len,flags);             //调用API发送函数  
  31. }  
  32. void CData::sevrecv(SOCKET s,char* buff,int len,int flags)  
  33.                                                 //自定
    义服务器接收函数  
  34. {  
  35.  recv(s,buff,len,flags);                        //调用API接收函数  
  36.   }  
  37. void CData::connect()  
  38. {  
  39. sockaddr_in addr;                               //定义地址结构变量  
  40.  addr.sin_family=AF_INET;                       //填充地址结构  
  41. addr.sin_port=htons(80);                        //指定监听端口为80  
  42. addr.sin_addr.S_un.S_addr=inet_addr(str14); //指定主机IP地址  
  43.  if(connect(s,( sockaddr*)addr,sizeof(addr),NULL)==-1)  
  44.                                                 //连接服务器  
  45. {  
  46.   MessageBox("连接服务器失败!");                   //提
    示用户连接服务器失败  
  47.   }  
  48. }  
  49. void CData::send(SOCKET s,char* buff,int len,int flags)  
  50.                                                 //自定客户端发送函数  
  51. {  
  52.   GetDlgItem(IDC_EDIT1)->GetWindowText(str);  
  53.                                                 //获取用户输入的数据  
  54. send(s,str.GetBuffer(1),sizeof(str),NULL);  
  55.                                                 //发送信息  
  56. GetDlgItem(IDC_EDIT2)->GetWindowText(str1);  
  57.                                                 //获取
    信息显示框中的内容  
  58. str1+="\r\n";                                   //添加回车换行符  
  59. str1+=str;                                      //连接字符串  
  60. GetDlgItem(IDC_EDIT2)->SetWindowText(str1);  
  61.                                                 //设置
    信息显示框的内容  
  62. }  
  63. void CData::recv(SOCKET s,char* buff,int len,int flags)  
  64.                                                 //自定
    义客户端接收函数  
  65. {  
  66.   char buff[1024];                              //定义字符缓冲区  
  67.  memset(&buff,0,1024);                          //初始
    化字符缓冲区  
  68.  recv(s,&buff,1024,NULL);                       //接收数据  
  69. }  
  70. void CData::~CData()                            //析构函数  
  71. {  
  72.   } 

上面的代码已经基本实现了自定义CData的基本方法。用户在使用该类时,必须在程序中包含该头文件Data.h。否则,用户将不能正确使用自定义类CData。

2.使用CData类

用户在程序需要使用自定义类CData时,首先需要包含该类头文件。代码如下:

  1. ...                         //省略部分代码  
  2. #include "Data.h"           //包含自定义类头文件 

注意:在VC中包含头文件时,如果所包含的头文件是系统定义的头文件,则使用符号"< >"括起来。否则,使用符号"" ""括起来。

然后,再定义自定义类对象。代码如下:

  1. ...                         //省略部分代码  
  2. CData dat;                  //定义类对象 

完成以上步骤后,用户便可以在程序中使用该对象调用相关的成员函数了。例如,当服务器端转发消息时,应该使用CData类中服务器发送函数对消息进行发送。代码如下:

  1. void CQQDlg::Onsoc(WPARAM wParam,LPARAM lParam)  
  2. {  
  3.     switch (lParam)                     //判断套接字事件  
  4. {  
  5.        ...                              //省略部分代码  
  6.     case FD_READ:                       //套接字读取事件  
  7.        {  
  8.         ...                             //省略
    部分读取事件响应代码  
  9.       for(int i=0;i<5;i++)  
  10. {  
  11.   if(msg[i].qq.m_name1== m_list.GetItemText(i,3))  
  12.                                         //判断昵称是否存在  
  13. {  
  14. dat.send(msg[i].s,&msg[i].qq.msg,1024,NULL);  
  15.                                         //使用
    对象将信息转发到接收方  
  16.   }  

用户使用自定义类CData中的成员时,仅需要使用该类对象对函数进行调用即可。所以,在本节中,不再对该类中其他的成员函数进行举例调用,请用户自行参考随书光盘中的实例代码。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇11.3.1 信件格式和内容 下一篇11.1.2 客户端(3)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: