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

本文介绍了一种非阻塞方式下CSocket类的服务端与客户端实现方法,通过继承CSocket并覆盖OnAccept和OnReceive方法,实现了不需要额外线程的网络通信。服务端能够监听并接受多个客户端的连接,客户端则可以发送和接收数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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. };

href="http://www.j2megame.org/wupei/plugins/plogeshi/styles/plogeshi.css" type="text/css" rel="stylesheet" />

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

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

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. }

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

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

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值