友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

VC语言6.0程序设计从入门到精通-第62部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


                                                                                                第 11 章    网络编程  



     表 11…10                          CChatServerDoc 类成员函数及其说明  



                       成员函数                                                          说明  

void ProcessAccept()                                        当监听到客户端连接时调用此函数进行处理  

void ProcessReceive(CClientSocket* pSocket)                 当接收到信息时调用此函数,进行信息接收等操作  

CMsg* ReadMsg(CClientSocket* pSocket)                       接收信息  

void SendMsg(CClientSocket* pSocket; CMsg* pMsg)            发送信息  

void SendToAllClients(int nCode)                            给各客户端发送消息  

CMsg*     AssembleMsg(CClientSocket*       pSocket;   int   封装消息,nCode 指定消息类型  

nCode)  

void SendForNewer(CMsg* pMsg)                            给各客户端发送消息,告知有新用户加入  

void UpdateMessageView(LPCTSTR lpszMessage)                 更新服务器聊天信息视图  

void    UpdateChattersListView(CString        sName     ;                          

                                                            更新服务器用户列表视图  

CClientSocket* pSocket)  

BOOL IsUsedName(CString sNickName)                          检查新登录的用户其用户名是否已被使用  

void CloseSocket(CClientSocket* pSocket)                    关闭连接  

void DeleteChatter(CMsg* pMsg)                              删除用户  

virtual void DeleteContents()                               当程序退出时做一些关闭、删除处理  



     下面为各函数编写代码。首先在构造函数中将各成员变量初始化,代码如下:  



    CChatServerDoc::CChatServerDoc()  



     {  



          // TODO: add one…time construction code here  



          m_pSocket = NULL;  



          m_msgList。RemoveAll();  



          m_connectionList。RemoveAll();  



          bIsNewChatter = TRUE;  



          m_ChattersList = 〃〃;  



     }  



    接着为“设定端口”菜单项添加响应函数,代码如下:  



    void CChatServerDoc::OnSetport()    



     {  



          // TODO: Add your mand handler code here  



          CPortDlg dlg;  



          if(dlg。DoModal() == IDOK)  



          {  



                //创建一个新的类进行监听  



                m_pSocket = new CListeningSocket(this);  



                if (m_pSocket…》Create(dlg。m_Port))  



                {  



                      if (m_pSocket…》Listen())  



                            return;  



                }  



          }  



     }  



                                                                                                             ·301 ·  


…………………………………………………………Page 313……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



      为函数 ProcessAccept()添加如下代码:  



      void CChatServerDoc::ProcessAccept()  



      {  



            //创建一个新的 Socket 来处理与客户端的数据交互  



            CClientSocket* pSocket = new CClientSocket(this);  



            //如果接受客户端的连接请求  



            if (m_pSocket…》Accept(*pSocket))  



            {  



                  //初始化  



                  pSocket…》Init();  



                  //将此连接 socket 加入连接链表中  



                  m_connectionList。AddTail(pSocket);  



            }       



            //如果不接受连接  



            else  



                  delete pSocket;  



      }  



      为函数 ProcessReceive()添加如下代码:  



      void CChatServerDoc::ProcessReceive(CClientSocket* pSocket)  



      {  



            CMsg* pMsg;    //接收的消息  



            CString sName;    //用户名  



            BOOL bIsUsedName = FALSE;    //用户名是否已使用  



            bIsNewChatter = FALSE;    //是否为新用户  



            do  



            {  



                  //接收消息  



                  pMsg = ReadMsg(pSocket);  



                  //如果此消息是发送的新的用户名(在用户登录时客户端先发此消息)  



                  if(pMsg…》code == SENDING_NICKNAME)  



                  {  



                         sName = pMsg…》m_strText;  



                         bIsNewChatter = TRUE;  



                         //检查此用户名是否已使用  



                         if(IsUsedName(sName))  



                               bIsUsedName = TRUE;  



                  }  



                  //如果连接已关闭则退出  



                  if (pMsg…》m_bClose)  



                  {  



 ·302 ·  


…………………………………………………………Page 314……………………………………………………………

                                                                                             第 11 章    网络编程  



             break;  



       }  



  }  



  while (!pSocket…》m_pArchiveIn…》IsBufferEmpty());  



  



  //如果是用户登录  



  if(bIsNewChatter)  



  {  



       //如果此用户名没有被使用  



       if(!bIsUsedName)  



       {  



             //发送消息通知各客户端  



             pMsg…》code = SENDING_CHATTERS_LIST;  



             m_ChattersList += sName + 〃:〃;  



             pMsg…》m_strText = m_ChattersList;  



             SendForNewer(pMsg);  



       }  



       //如果用户名已使用  



       else  



       {  



             //发消息通知此客户端  



             CMsg* msg = new CMsg;  



             msg…》Init();  



             msg…》code =    USED_NAME;  



             CString string;  



             string。Format(〃用户名已被使用!〃);  



             msg…》m_strText = string;  



             SendMsg(pSocket; msg);  



       }  



       bIsNewChatter = FALSE;  



       bIsUsedName = FALSE;  



  }  



  //如果消息表明该客户端已关闭连接  



  if (pMsg…》m_bClose)  



  {  



       //发送消息通知各客户端  



       SendToAllClients(NORMAL_MESSAGE);  



       //在视图中将该用户删除  



       DeleteChatter(pMsg);  



       //关闭连接  



                                                                                                           ·303 ·  


…………………………………………………………Page 315……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



                   CloseSocket(pSocket);  



                   //通知各客户端更新用户列表  



                   SendToAllClients(SENDING_CHATTERS_LIST);  



             }  



             //如果是普通消息,发送给各客户端  



             else  



                   SendToAllClients(NORMAL_MESSAGE);  



       }  



       为 ReadMsg() 函数编写如下代码:  



      CMsg* CChatServerDoc::ReadMsg(CClientSocket* pSocket)  



       {  



             static CMsg msg;  



             TRY  



             {  



                   //接收数据  



                   pSocket…》ReceiveMsg(&msg);  



                   //如果是新用户登录则更新用户列表  



                   if(msg。code == SENDING_NICKNAME)  



                   {  



                          UpdateChattersListView(msg。m_strText ; pSocket);  



                   }  



                   //如果是普通信息则更新聊天信息列表,并将信息加入到 m_msgList 链表中  



                   if(msg。code == NORMAL_MESSAGE)  



                   {  



                          UpdateMessageView(msg。m_strText);  



                          m_msgList。AddTail(msg。m_strText);  



                   }  



             }  



             CATCH(CFileException; e)  



             {  



                   CString strTemp;  



                   strTemp。Format(〃无法读取数据!〃);  



                   UpdateMessageView(strTemp);  



                   msg。m_bClose = TRUE;  



             }  



             END_CATCH  



             return &msg;  



       }  



       为 SendMsg()函数编写如下代码:  



      void CChatServerDoc::SendMsg(CClientSocket* pSocket; CMsg* pMsg)  



 ·304 ·  


…………………………………………………………Page 316……………………………………………………………

                                                                                                   第 11 章    网络编程  



{  



      TRY  



      {  



             //调用 CClientSocket 的函数发送消息  



             pSocket…》SendMsg(pMsg);  



      }  



      CATCH(CFileException; e)  



      {  



             CString strTemp;  



             strTemp。Format(〃无法发送数据!〃);  



             UpdateMessageView(strTemp);  



      }  



      END_CATCH  



}  



为函数 IsUsedName()编写如下代码:  



BOOL CChatServerDoc::IsUsedName(CString sNickName)  



{  



      CString tempStr; tempList; sName;  



      tempStr = 〃〃;  



      tempList = m_ChattersList;  



      do  



      {  



             //利用“:”得到名字并查找(客户端发送的消息前面都有用户名加“:”)  



             sName = tempList。Left(tempList。Find(〃:〃; 0));  



             tempList = tempList。Mid(tempList。Find(〃:〃; 0) + 1);  



             //找到则返回真  



             if(sName == sNickName)  



                   return TRUE;  



      }while(tempList。Find(〃:〃 ; 0) != …1);  



      //未被使用则返回假  



      return FALSE;  



}  



为函数 AssembleMsg()编写如下代码:  



CMsg* CChatServerDoc::AssembleMsg(CClientSocket* pSocket ; int nCode)  



{  



      static CMsg msg;  



      msg。Init();  



      for (POSITION pos1 = m_msgList。FindIndex(pSocket…》m_nMsgCount); pos1 != NULL;)  



      {  



             //信息内容  



                                                                                                                 ·305 ·  


…………………………………………………………Page 317……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



                   msg。m_strText = m_msgList。GetNext(pos1);               



                   //信息类型  



                   msg。code = nCode;  



             }  



             pSocket…》m_nMsgCount = m_msgList。GetCount();  



             return &msg;  



       }  



       为函数 SendForNewer()编写如下代码:  



      void CChatServerDoc::SendForNewer(CMsg* pMsg)  



       {  



             for(POSITION pos = m_connectionList。GetHeadPosition(); pos != NULL;)  



             {  



                   //对每个客户端都发送信息  



                   CClientSocket* pSocket = (CClientSocket*)m_connectionList。GetNext(pos);  



                   if (pSocket != NULL)  



                          SendMsg(pSocket; pMsg);  



             }  



       }  



       为函数 SendToAllClients()编写如下代码:  



      void CChatServerDoc::SendToAllClients(int nCode)  



  
返回目录 上一页 下一页 回到顶部 1 2
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!