单例类
描述:
指在整个系统生命期中,一个类最多只能有一个实例(instance)存在,使得该实例的唯一性(实例是指一个对象指针)
用法:
1. 将构造函数的访问属性设置为private
2. 提供一个GetInstance()静态成员函数,只能供用户访问唯一一个实例
3. 定义一个静态成员指针,用来供用户获取
4. 重载 (=)赋值操作符以及拷贝构造函数,并设为private, 避免对象间拷贝,复制
为了防止多次外部多次创建服务器CServerSocket对象从而初始化多次网络环境造成不可预计的后果,采用安全的编程方法
封装:
.h
class CServerSocket
{
public:
//提供一个GetInstance()静态成员函数
static CServerSocket* getInstance() {
if (m_instance == NULL) {//静态函数没有this指针,所以无法直接访问成员变量
m_instance = new CServerSocket();
}
return m_instance;
}
bool InitScoket() {
if (m_sock == -1) return false;
sockaddr_in serv_adr;
memset(&serv_adr, 0, sizeof(serv_adr));//对地址进行清零
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = INADDR_ANY;//监听所有的ip
serv_adr.sin_port = htons(9527);
//绑定端口
if (bind(m_sock, (sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) {
return false;
}
if (listen(m_sock, 1) == -1) {
return false;
}
return true;
}
bool AcceptClient() {
sockaddr_in client_addr;
char buffer[1024];
int cli_sz = sizeof(client_addr);
m_client = accept(m_sock, (sockaddr*)&client_addr, &cli_sz);
if (m_client == -1) return false;
return true;
}
int DealCommand() {
if (m_client == -1)return false;
char buffer[1024] = "";
while (true) {
int len = recv(m_client, buffer, sizeof(buffer), 0);
if (len <= 0) {
return -1;
}
//处理命令
}
}
bool Send(const char* pData, int nSize) {
if (m_client == -1)return false;
return send(m_client, pData, nSize, 0) > 0;
}
private:
SOCKET m_client;
SOCKET m_sock;
// 重载 (=)赋值操作符以及拷贝构造函数,并设为private, 避免对象间拷贝,复制
CServerSocket& operator=(const CServerSocket& ss) {}
CServerSocket(const CServerSocket& ss) {}
//将构造函数的访问属性设置为private
CServerSocket() {
m_client = INVALID_SOCKET;//INVALID_SOCKET =-1
if (InitSockEnv() == FALSE) {//初始化套接字失败
MessageBox(NULL, _T("无法初始化套接字环境,请检查网络设置"), _T("初始化错误!"), MB_OK | MB_ICONERROR);
exit(0);//直接结束
}
//创建一个socket
m_sock = socket(PF_INET, SOCK_STREAM, 0);//使用TCP故使用SOCK_STREAM
}
~CServerSocket() {
closesocket(m_sock);
WSACleanup();//确保被调用
}
BOOL InitSockEnv() {
//打开网络库,返回值为int类型,打开成功返回0
WSADATA data;
if (WSAStartup(MAKEWORD(1, 1), &data) != 0) {
return FALSE;
}
return TRUE;
}
static void releaseInstance() {
if (m_instance != NULL) {
CServerSocket* tmp = m_instance;
m_instance = NULL;
delete tmp;
}
}
//定义一个静态成员指针,用来供用户获取
static CServerSocket* m_instance;
class CHelper {
public:
CHelper() {
CServerSocket::getInstance();
}
~CHelper() {
CServerSocket::releaseInstance();
}
};
static CHelper m_helper;
};
.cpp
CServerSocket* CServerSocket::m_instance = NULL;
CServerSocket::CHelper CServerSocket::m_helper;
CServerSocket* pserver = CServerSocket::getInstance();
调用:
CServerSocket* pserver = CServerSocket::getInstance();//创建单例
int count = 0;
//初始化套接字
if (pserver->InitScoket() == false) {
MessageBox(NULL, _T("网络初始化异常,请检查网络状态"), _T("网络初始化失败"), MB_OK | MB_ICONERROR);
exit(0);
}
while (CServerSocket::getInstance() !=NULL) {
if (pserver->AcceptClient() == false) {
if (count >= 3) {
MessageBox(NULL, _T("多次无法正常接入用户,结束程序"), _T("接入用户失败"), MB_OK | MB_ICONERROR);
exit(0);
}
MessageBox(NULL, _T("无法正常接入用户,自动重试"), _T("接入用户失败"), MB_OK | MB_ICONERROR);
count++;
}
int ret = pserver->AcceptClient();
}