VC下CSocket非阻塞方式下的连接框架
2008-02-17 18:03
204 查看
CSocket非阻塞方式(不用自己建立线程)
1.服务端
应用非阻塞方式需要自己声明一个类继承CSokcet类
// MySocket.h : header file
class CMySocket : public CSocket
{
// Attributes
public:
CServerDlg* m_pServerDlg; //主窗口指针
// Operations
public:
CMySocket();
virtual ~CMySocket();
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMySocket)
public:
virtual void OnAccept(int nErrorCode); //当准备连接时,系统调用
virtual void OnReceive(int nErrorCode); //当准备接受消息时,系统调用
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CMySocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// Implementation
protected:
};
// MySocket.cpp : implementation file
CMySocket::CMySocket(CServerDlg* pServerDlg)
{
m_pServerDlg = pServerDlg; //用于处理消息
}
CMySocket::~CMySocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMySocket, CSocket)
//{{AFX_MSG_MAP(CMySocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/////////////////////////////////////////////////////////////////////////////
// CMySocket member functions
void CMySocket::OnAccept(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
//处理连接请求
m_pServerDlg->ServerAccept();
CSocket::OnAccept(nErrorCode);
}
void CMySocket::OnReceive(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
//处理接受消息请求
m_pServerDlg->ServerReceive(this); //传入本身Socket
CSocket::OnReceive(nErrorCode);
}
////////////////////////////////////////////////////
// ServerDlg.h : header file
CMySocket* m_pServer; //添加Socket指针
CPtrArray m_ConnectArray; //用于保存连接指针的容器
////////////////////////////////////////////////////
// ServerDlg.cpp : implementation file
void CServerDlg::ServerInit() //服务端初始化,供别的函数调用
{
m_pServer = new CMySocket(this); //传入窗口指针
if(!m_pServer->Create(61111)) //指明端口
{
MessageBox("服务器初始化错误n程序退出");
delete m_pServer;
return;
}
if(!m_pServer->Listen()) //开始监听
{
MessageBox("服务器初始化错误n程序退出");
delete m_pServer;
return;
}
}
void CServerDlg::ServerAccept() //有客户端连接,系统调用
{
CMySocket* connect = new CMySocket(this); //建立连接用Socket
if(!m_pServer->Accept(*connect))
{
MessageBox("客户端连接错误!");
delete connect;
}
m_ConnectArray.Add(connect); //把这个连接添加进容器
}
void CServerDlg::ServerReceive(CMySocket* connect) //连接发来数据,准备接收
{
char msg[100];
connect->Receive(msg,100); //接受数据
MessageBox(CString(msg));
}
void CServerDlg::SocketSend(CMySocket* connect, CString msg) //Socket发送数据
{
char* str= msg.GetBuffer(msg.GetLength());
connect->Send(str,msg.GetLength()); //发送数据
}
void CServerDlg::ServerSendToAllConnect(char* pChar) //发送给所有客户端数据的函数
{
for(int i=0; i<=m_ConnectArray.GetSize()-1; i++) //遍历连接容器
{
((CMySocket*)m_ConnectArray[i])->Send(pChar,100); //发送
}
}
void CServerDlg::ServerClose()
{
//发送踢出消息,使客户端自动断开连接
//ServerSendToAllConnect("01"); //用户实现方式不同
//清理服务器连接
m_pServer->Close();
delete m_pServer;
//清理客户端连接
for(int i=0; i<=m_ConnectArray.GetSize()-1; i++)
{
((CMySocket*)m_ConnectArray[i])->Close();
delete (CMySocket*)m_ConnectArray[i];
}
m_ConnectArray.RemoveAll();
}
注意:客户端连接与断开时,必须根据实际情况,更新存放连接容器,否则会出现错误
2.客户端
//也使用了CMySocket,代码同服务端CMySokcet一样,只不过不用响应OnAccept事件
//////////////////////////////////////////////////
// ClientDlg.h : header file
CMySocket* m_pClient; //本身连接用Socket
//////////////////////////////////////////////////
// ClientDlg.cpp : implementation file
bool CClientDlg::ClientInit()
{
m_pClient = new CMySocket(this);
if(!m_pClient->Create())
{
delete m_pClient;
MessageBox("客户端初始化错误!n");
return 0;
}
if(!WSAEINVAL==m_pClient->Connect("127.0.0.1",61111)) //连接服务器IP的某端口(端口须和上面一直)
{
delete m_pClient;
MessageBox("客户端初始化错误!n");
return 0;
}
return 1;
}
void CClientDlg::ClientReceive(CMySocket* Socket) //客户端接受数据
{
char ReceiveChar[100];
Socket->Receive(ReceiveChar,100);
CString ReceiveMsg(ReceiveChar);
MessageBox(ReceiveMsg);
}
void CClientDlg::ClientSend(CString msg) //客户端发送数据
{
char* str= msg.GetBuffer(msg.GetLength());
m_pClient->Send(str,msg.GetLength()); //发送数据
}
bool CClientDlg::ClientClose() //客户端断开连接
{
//应发送数据,告诉服务端,自己断开连接,更新服务端容器内的连接
//m_Client->Send("02",100);//用户实现方式不同
if(m_pClient)
{
m_pClient->Close();
delete m_pClient;
return 1;
}
return 0;
}
注意:客户端连接与断开时,必须根据实际情况,让服务端只是,自己连接与断开了,及时更新服务端的存放连接的容器
下面是我做的一个超级简单的聊天室的流程图,仅供参考
1.服务端
应用非阻塞方式需要自己声明一个类继承CSokcet类
// MySocket.h : header file
class CMySocket : public CSocket
{
// Attributes
public:
CServerDlg* m_pServerDlg; //主窗口指针
// Operations
public:
CMySocket();
virtual ~CMySocket();
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMySocket)
public:
virtual void OnAccept(int nErrorCode); //当准备连接时,系统调用
virtual void OnReceive(int nErrorCode); //当准备接受消息时,系统调用
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CMySocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// Implementation
protected:
};
// MySocket.cpp : implementation file
CMySocket::CMySocket(CServerDlg* pServerDlg)
{
m_pServerDlg = pServerDlg; //用于处理消息
}
CMySocket::~CMySocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMySocket, CSocket)
//{{AFX_MSG_MAP(CMySocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/////////////////////////////////////////////////////////////////////////////
// CMySocket member functions
void CMySocket::OnAccept(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
//处理连接请求
m_pServerDlg->ServerAccept();
CSocket::OnAccept(nErrorCode);
}
void CMySocket::OnReceive(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
//处理接受消息请求
m_pServerDlg->ServerReceive(this); //传入本身Socket
CSocket::OnReceive(nErrorCode);
}
////////////////////////////////////////////////////
// ServerDlg.h : header file
CMySocket* m_pServer; //添加Socket指针
CPtrArray m_ConnectArray; //用于保存连接指针的容器
////////////////////////////////////////////////////
// ServerDlg.cpp : implementation file
void CServerDlg::ServerInit() //服务端初始化,供别的函数调用
{
m_pServer = new CMySocket(this); //传入窗口指针
if(!m_pServer->Create(61111)) //指明端口
{
MessageBox("服务器初始化错误n程序退出");
delete m_pServer;
return;
}
if(!m_pServer->Listen()) //开始监听
{
MessageBox("服务器初始化错误n程序退出");
delete m_pServer;
return;
}
}
void CServerDlg::ServerAccept() //有客户端连接,系统调用
{
CMySocket* connect = new CMySocket(this); //建立连接用Socket
if(!m_pServer->Accept(*connect))
{
MessageBox("客户端连接错误!");
delete connect;
}
m_ConnectArray.Add(connect); //把这个连接添加进容器
}
void CServerDlg::ServerReceive(CMySocket* connect) //连接发来数据,准备接收
{
char msg[100];
connect->Receive(msg,100); //接受数据
MessageBox(CString(msg));
}
void CServerDlg::SocketSend(CMySocket* connect, CString msg) //Socket发送数据
{
char* str= msg.GetBuffer(msg.GetLength());
connect->Send(str,msg.GetLength()); //发送数据
}
void CServerDlg::ServerSendToAllConnect(char* pChar) //发送给所有客户端数据的函数
{
for(int i=0; i<=m_ConnectArray.GetSize()-1; i++) //遍历连接容器
{
((CMySocket*)m_ConnectArray[i])->Send(pChar,100); //发送
}
}
void CServerDlg::ServerClose()
{
//发送踢出消息,使客户端自动断开连接
//ServerSendToAllConnect("01"); //用户实现方式不同
//清理服务器连接
m_pServer->Close();
delete m_pServer;
//清理客户端连接
for(int i=0; i<=m_ConnectArray.GetSize()-1; i++)
{
((CMySocket*)m_ConnectArray[i])->Close();
delete (CMySocket*)m_ConnectArray[i];
}
m_ConnectArray.RemoveAll();
}
注意:客户端连接与断开时,必须根据实际情况,更新存放连接容器,否则会出现错误
2.客户端
//也使用了CMySocket,代码同服务端CMySokcet一样,只不过不用响应OnAccept事件
//////////////////////////////////////////////////
// ClientDlg.h : header file
CMySocket* m_pClient; //本身连接用Socket
//////////////////////////////////////////////////
// ClientDlg.cpp : implementation file
bool CClientDlg::ClientInit()
{
m_pClient = new CMySocket(this);
if(!m_pClient->Create())
{
delete m_pClient;
MessageBox("客户端初始化错误!n");
return 0;
}
if(!WSAEINVAL==m_pClient->Connect("127.0.0.1",61111)) //连接服务器IP的某端口(端口须和上面一直)
{
delete m_pClient;
MessageBox("客户端初始化错误!n");
return 0;
}
return 1;
}
void CClientDlg::ClientReceive(CMySocket* Socket) //客户端接受数据
{
char ReceiveChar[100];
Socket->Receive(ReceiveChar,100);
CString ReceiveMsg(ReceiveChar);
MessageBox(ReceiveMsg);
}
void CClientDlg::ClientSend(CString msg) //客户端发送数据
{
char* str= msg.GetBuffer(msg.GetLength());
m_pClient->Send(str,msg.GetLength()); //发送数据
}
bool CClientDlg::ClientClose() //客户端断开连接
{
//应发送数据,告诉服务端,自己断开连接,更新服务端容器内的连接
//m_Client->Send("02",100);//用户实现方式不同
if(m_pClient)
{
m_pClient->Close();
delete m_pClient;
return 1;
}
return 0;
}
注意:客户端连接与断开时,必须根据实际情况,让服务端只是,自己连接与断开了,及时更新服务端的存放连接的容器
下面是我做的一个超级简单的聊天室的流程图,仅供参考
相关文章推荐
- VC下CSocket非阻塞方式下的连接框架
- VC MFC SDI/MDI框架各部分指针获取方式
- VC中ADO连接SQLSERVER的几种标准方式?
- win7 64 VC++ ado方式连接access 连接字符串
- VC连接ADO方式ACCESS数据库在WIN7下编译到XP下不能运行
- MFC VC++下ADO方式访问连接MySQL数据库 添加 删除 修改数据库
- VC++以ADO方式连接SQL SERVER
- VC MFC SDI/MDI框架各部分指针获取方式
- VC MFC SDI/MDI框架各部分指针获取方式
- VC MFC SDI/MDI框架各部分指针获取方式
- Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式。
- ADO方式连接带有密码的Access数据库文件(VC、Delphi)
- ThinkPHP框架基于PDO方式连接数据库操作示例
- VC中ADO连接SQLSERVER的几种标准方式
- VC MFC SDI/MDI框架各部分指针获取方式
- VC中ADO连接SQLSERVER的几种标准方式
- VC MFC SDI/MDI框架各部分指针获取方式
- VC连接ADO方式ACCESS数据库在WIN7下编译到XP下不能运行解决方法
- VC++ 通过ADO方式连接SQLServer20XX出现sqlserver 不存在或者拒绝连接错误
- VC MFC SDI/MDI框架各部分指针获取方式