CSocket非阻塞方式(不用自己建立线程)
1.服务端
应用非阻塞方式需要自己声明一个类继承CSokcet类
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:
-
-
};
href="http://www.j2megame.org/wupei/plugins/plogeshi/styles/plogeshi.css" type="text/css" rel="stylesheet" />
-
// 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;
-
}
注意:客户端连接与断开时,必须根据实际情况,让服务端只是,自己连接与断开了,及时更新服务端的存放连接的容器
下面是我做的一个超级简单的聊天室的流程图,仅供参考