基本步骤
1、构造、析构函数设置为私有
2、operator=和拷贝也设置为私有
private:
CSocket& operator=(const CSocket& cs) {
...
}
CSocket(const CSocket& cs) {
...
}
CSocket() {
...
}
~CSocket() {
...
}
3、写一个公有的 静态 类指针 函数static 类* getInstance(){},类外可通过类名::函数名进行访问
public:
static CSocket* getInstance() {
if (m_instance == NULL) {
m_instance = new CSocket();
}
return m_instance;
}
4、声明一个私有的 静态 类指针实例 类* m_instance(PS:静态函数没有this指针,无法直接访问成员变量)
private:
static CSocket* m_instance;
5、4中的静态 类指针实例仅仅为声明,没有实现,类似extern,在外部(类.cpp)写实现,类* 类::m_instance = NULL;
CSocket* CSocket::m_instance = NULL;
6、外部写一个类指针pserver=类::getInstance(); 即pserver=4中的实例
CSocket* pserver = CSocket::getInstance();
7、类中写一个辅助类CHelper,用来调用类的析构(已私有)函数
private:
static void releaseInstance() {
if (m_instance != NULL) {
CSocket* tmp = m_instance;
m_instance = NULL;
delete tmp;
}
}
class CHelper {
public:
CHelper() {
CSocket::getInstance();
}
~CHelper() {
CSocket::releaseInstance();
}
};
private:
static CHelper m_helper;
8、类外初始化m_helper
CSocket::CHelper CSocket::m_helper;
完整代码示例
''''Socket.h''''
#pragma once
#include <WinSock2.h>
#include<iostream>
class CSocket
{
private:
SOCKET m_sock;
SOCKET m_client;
public:
static CSocket* getInstance() {
if (m_instance == NULL) {
m_instance = new CSocket();
}
return m_instance;
}
//套接字初始化
bool InitSocket() {
if (INVALID_SOCKET == m_sock)
{
printf("socket errorNum = %d\n", GetLastError());
return FALSE;
}
SOCKADDR_IN serv_adr; //定义主机
serv_adr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //支持任意地址
serv_adr.sin_family = AF_INET; //协议族是IPV4
serv_adr.sin_port = htons(6000); //端口6000
if (SOCKET_ERROR == bind(m_sock, (SOCKADDR*)&serv_adr, sizeof(SOCKADDR))) {
printf("bind errorNum = %d\n", GetLastError());
return FALSE;
}
//最大监听数目5
if (SOCKET_ERROR == listen(m_sock, 5)) { //等待接入的队列的最大长度
printf("listen errorNum = %d\n", GetLastError());
return FALSE;
}
return TRUE;
}
bool AcceptClient() {
SOCKADDR_IN client_adr; //定义分机
int cli_sz = sizeof(client_adr);
// 主机去处理客户端连接
m_client = accept(m_sock, (SOCKADDR*)&client_adr, &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;
}
//TODO:处理命令
}
}
bool Send(const char* pData, int nSize) {
if (m_client == -1) return FALSE;
return send(m_client, pData, nSize, 0) > 0;
}
private:
CSocket& operator=(const CSocket& cs) {
m_sock = cs.m_sock;
m_client = cs.m_client;
}
CSocket(const CSocket& cs) {
m_sock = cs.m_sock;
m_client = cs.m_client;
}
CSocket() {
//m_sock = INVALID_SOCKET;
m_client = INVALID_SOCKET;
if (InitSockEnv() == false) {
std::cout << "套接字环境初始化失败\n";
exit(0); //终止当前运行的程序,并返回一个状态码给操作系统
}
m_sock = socket(AF_INET, SOCK_STREAM, 0); //IPv4
}
~CSocket() {
// 关闭总机
closesocket(m_sock);
// 清理网络环境
WSACleanup();
}
//网络环境初始化
bool InitSockEnv() {
// 加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
// 初始化套接字库
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return false;
}
// 检查返回的Winsock版本是否为1.1
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup(); //清理Winsock资源
return false;
}
return true;
}
private:
static void releaseInstance() {
if (m_instance != NULL) {
CSocket* tmp = m_instance;
m_instance = NULL;
delete tmp;
}
}
class CHelper {
public:
CHelper() {
CSocket::getInstance();
}
~CHelper() {
CSocket::releaseInstance();
}
};
private:
static CHelper m_helper;
static CSocket* m_instance;
};
//extern关键字用于声明一个变量或函数是在别的文件中定义的,
//或者是在程序的全局范围内定义的,而不是在当前的源文件中
extern CSocket server;
''''Socket.cpp''''
#include "Socket.h"
//CSocket server;
CSocket* CSocket::m_instance = NULL;
CSocket::CHelper CSocket::m_helper;
CSocket* pserver = CSocket::getInstance();