VC下CSocket非阻塞方式下的连接框架

来源:互联网 发布:mac word 简繁体转换 编辑:程序博客网 时间:2024/04/30 02:22
CSocket非阻塞方式(不用自己建立线程)

1.服务端
应用非阻塞方式需要自己声明一个类继承CSokcet类
  1. // MySocket.h : header file
  2. class CMySocket : public CSocket
  3. {
  4. // Attributes
  5. public:
  6.         CServerDlg* m_pServerDlg;       //主窗口指针
  7. // Operations
  8. public:
  9.         CMySocket();
  10.         virtual ~CMySocket();
  11.  
  12. // Overrides
  13. public:
  14.         // ClassWizard generated virtual function overrides
  15.         //{{AFX_VIRTUAL(CMySocket)
  16.         public:
  17.         virtual void OnAccept(int nErrorCode)//当准备连接时,系统调用
  18.         virtual void OnReceive(int nErrorCode)//当准备接受消息时,系统调用
  19.         //}}AFX_VIRTUAL
  20.  
  21.         // Generated message map functions
  22.         //{{AFX_MSG(CMySocket)
  23.                 // NOTE - the ClassWizard will add and remove member functions here.
  24.         //}}AFX_MSG
  25.  
  26. // Implementation
  27. protected:
  28.  
  29. };

  1. // MySocket.cpp : implementation file
  2.  
  3. CMySocket::CMySocket(CServerDlg* pServerDlg)
  4. {
  5.         m_pServerDlg = pServerDlg;      //用于处理消息
  6. }
  7.  
  8. CMySocket::~CMySocket()
  9. {
  10. }
  11.  
  12. // Do not edit the following lines, which are needed by ClassWizard.
  13. #if 0
  14. BEGIN_MESSAGE_MAP(CMySocket, CSocket)
  15.         //{{AFX_MSG_MAP(CMySocket)
  16.         //}}AFX_MSG_MAP
  17. END_MESSAGE_MAP()
  18. #endif  // 0
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CMySocket member functions
  22.  
  23. void CMySocket::OnAccept(int nErrorCode)
  24. {
  25.         // TODO: Add your specialized code here and/or call the base class
  26.         //处理连接请求
  27.         m_pServerDlg->ServerAccept();
  28.        
  29.         CSocket::OnAccept(nErrorCode);
  30. }
  31.  
  32. void CMySocket::OnReceive(int nErrorCode)
  33. {
  34.         // TODO: Add your specialized code here and/or call the base class
  35.         //处理接受消息请求
  36.         m_pServerDlg->ServerReceive(this);      //传入本身Socket
  37.  
  38.         CSocket::OnReceive(nErrorCode);
  39. }


  1. ////////////////////////////////////////////////////
  2. // ServerDlg.h : header file
  3.  
  4. CMySocket* m_pServer;   //添加Socket指针
  5. CPtrArray m_ConnectArray;       //用于保存连接指针的容器
  6.  
  7. ////////////////////////////////////////////////////
  8. // ServerDlg.cpp : implementation file
  9.  
  10. void CServerDlg::ServerInit()   //服务端初始化,供别的函数调用
  11. {
  12.         m_pServer = new CMySocket(this);        //传入窗口指针
  13.         if(!m_pServer->Create(61111))   //指明端口
  14.         {
  15.                 MessageBox("服务器初始化错误n程序退出");
  16.                 delete m_pServer;
  17.                 return;
  18.         }
  19.         if(!m_pServer->Listen())        //开始监听
  20.         {
  21.                 MessageBox("服务器初始化错误n程序退出");
  22.                 delete m_pServer;
  23.                 return;
  24.         }
  25. }
  26. void CServerDlg::ServerAccept() //有客户端连接,系统调用
  27. {
  28.         CMySocket* connect = new CMySocket(this);       //建立连接用Socket
  29.  
  30.         if(!m_pServer->Accept(*connect))
  31.         {
  32.                 MessageBox("客户端连接错误!");
  33.                 delete connect;
  34.         }
  35.        
  36.         m_ConnectArray.Add(connect);    //把这个连接添加进容器
  37. }
  38. void CServerDlg::ServerReceive(CMySocket* connect)      //连接发来数据,准备接收
  39. {
  40.         char msg[100];
  41.         connect->Receive(msg,100);      //接受数据
  42.         MessageBox(CString(msg));
  43. }
  44. void CServerDlg::SocketSend(CMySocket* connect, CString msg)    //Socket发送数据
  45. {
  46.         char* str= msg.GetBuffer(msg.GetLength());
  47.         connect->Send(str,msg.GetLength());     //发送数据
  48. }
  49. void CServerDlg::ServerSendToAllConnect(char* pChar)    //发送给所有客户端数据的函数
  50. {
  51.         for(int i=0; i<=m_ConnectArray.GetSize()-1; i++)        //遍历连接容器
  52.         {
  53.                 ((CMySocket*)m_ConnectArray[i])->Send(pChar,100);       //发送
  54.         }
  55. }
  56. void CServerDlg::ServerClose()
  57. {
  58.         //发送踢出消息,使客户端自动断开连接
  59.         //ServerSendToAllConnect("01"); //用户实现方式不同
  60.        
  61.         //清理服务器连接
  62.         m_pServer->Close();
  63.         delete m_pServer;
  64.  
  65.         //清理客户端连接
  66.         for(int i=0; i<=m_ConnectArray.GetSize()-1; i++)
  67.         {
  68.                 ((CMySocket*)m_ConnectArray[i])->Close();
  69.                 delete (CMySocket*)m_ConnectArray[i];
  70.         }
  71.         m_ConnectArray.RemoveAll();
  72. }

注意:客户端连接与断开时,必须根据实际情况,更新存放连接容器,否则会出现错误

2.客户端

  1. //也使用了CMySocket,代码同服务端CMySokcet一样,只不过不用响应OnAccept事件
  2.  
  3. //////////////////////////////////////////////////
  4. // ClientDlg.h : header file
  5. CMySocket* m_pClient;   //本身连接用Socket
  6.  
  7. //////////////////////////////////////////////////
  8. // ClientDlg.cpp : implementation file
  9.  
  10. bool CClientDlg::ClientInit()
  11. {
  12.         m_pClient = new CMySocket(this);
  13.         if(!m_pClient->Create())
  14.         {
  15.                 delete m_pClient;
  16.                 MessageBox("客户端初始化错误!n");
  17.                 return 0;
  18.         }
  19.  
  20.         if(!WSAEINVAL==m_pClient->Connect("127.0.0.1",61111))   //连接服务器IP的某端口(端口须和上面一直)
  21.         {
  22.                 delete m_pClient;
  23.                 MessageBox("客户端初始化错误!n");
  24.                 return 0;
  25.         }
  26.  
  27.         return 1;
  28. }
  29. void CClientDlg::ClientReceive(CMySocket* Socket)       //客户端接受数据
  30. {
  31.         char ReceiveChar[100];
  32.         Socket->Receive(ReceiveChar,100);
  33.         CString ReceiveMsg(ReceiveChar);
  34.         MessageBox(ReceiveMsg);
  35. }
  36. void CClientDlg::ClientSend(CString msg)        //客户端发送数据
  37. {
  38.         char* str= msg.GetBuffer(msg.GetLength());
  39.         m_pClient->Send(str,msg.GetLength());   //发送数据
  40. }
  41. bool CClientDlg::ClientClose()          //客户端断开连接
  42. {
  43.         //应发送数据,告诉服务端,自己断开连接,更新服务端容器内的连接
  44.         //m_Client->Send("02",100);//用户实现方式不同
  45.        
  46.         if(m_pClient)
  47.         {
  48.                 m_pClient->Close();
  49.                 delete m_pClient;
  50.                 return 1;
  51.         }
  52.         return 0;
  53. }

注意:客户端连接与断开时,必须根据实际情况,让服务端只是,自己连接与断开了,及时更新服务端的存放连接的容器

下面是我做的一个超级简单的聊天室的流程图,仅供参考
超级简易聊天室流程图

 
原创粉丝点击