Select模型设计200人服务器

/*
Select模型设计200人服务器

问题描述:
    利用select模型设计能够同时支持200人在线的服务器框架

核心难点:
    1. select模型缺省情况下最多能支持64人同时在线
    2. 如何精确控制在线人数不超过200人

解决思路:多线程处理:

    1. 主线程负责接收客户端连接

    2. 子线程负责与客户端进行通信,每个线程最多处理64个客户请求


数据维护:
    1. 主线程负责服务器逻辑控制,维护服务器数据对象,其具体实现见服务器对象类(CService设计)设计
    2. 每个子线程负责维护一个线程对象数据类型其类型,其具体类型见线程数据对象类(CThreadObj)设计

*/


主函数代码

#include "stdafx.h"
#include "Service.h"
#include "../InitSocket.h"

CInitSocket g_InitLib;

int main()
{	
	CService Serv(4567);

	Serv.RunServ();

    return 0;
}

服务器类设计


/*
CService对象设计
1. 数据对象
    1) 监听套接字
    2) 端口
    3) IP
    4) 线程对象列表

2. 数据处理方法
    1)服务器初始化(创建套接字,绑定套接字,监听套接字)
    2)运行服务器    
    (接收到客户连接,将通信套接字交给对应线程对象,
        如果线程对象没有启动,则启动对应的线程)
    - 成功接收连接
    - 是否有空余线程对象
        否 创建新的线程对象,加入列表,启动线程
        是 将套接字交给新的线程    
        - 线程是否启动    否 启动想成
                        是 next
*/

#include "ThreadObj.h"
class CService
{
public:
	CService();
	CService(USHORT uPort, const char *pszIP = NULL);
	~CService();

public:
	//初始化服务器
	bool InitServ(USHORT uPort, const char *pszIP = NULL);
	//运行服务器
	bool RunServ();

private:
	//监听套接字
	SOCKET m_sListen;
	//服务器端口号
	USHORT m_uPort;
	//服务器IP
	ULONG m_uIP;
	//服务器线程列表
	list<CThreadObj> m_ThreadList;
};

线程对象设计

/*
线程对象类设计思路
1. 每个线程负责维护的数据对象
    1) 当前线程需要处理的socket集合
    2) 当前线程socket数量
    3) 当前系统socket总数
    4)    当前线程是够正在运行

2. 数据处理方法
    1) 套接字集合处理方法
        增,删,改,查,清空,
    2) 判断方法
        是否为空,是否已满,线程是否运行
    3)Get方法
        获取自身引用,获取线程socket总数,获取系统socket总数

3. 运算符重载
    1) [] 获取指定索引位置的socket集合对应的socket对象
    2) += 添加socket
    3) == 对象是否相等,对应的socket是否在集合中
    4) -= 移除对象

4. 构造函数
    缺省构造        需要
    类型转换构造    需要(SOCKET s)
    拷贝构造        不需要
    移动构造        不需要
    其他构造        不需要
*/

class CThreadObj
{
public:
    CThreadObj();
    ~CThreadObj();

private:
    // 当前线程套接字集合
    fd_set m_fdCurThreadClient;
    // 当前线程套接字总数
    int m_CurThreadCount;
    // 当前系统套接字总数
    static int m_nSysTotal;
    // 当前线程是否启动
    bool m_bThreadRun;
public:
    // 向当前线程中添加套接字 s
    bool AddSocket(SOCKET s);
    //从当前线程中移除套接字 s
    bool RemoveSocket(SOCKET s);
    // 判断套接字是否在当前线程
    bool IsSet(SOCKET s);
    // 当前线程套接字是否为 0
    bool IsEmpty();
    // 当前系统套接字是否已满
    bool IsFull();
    // 当前线程是否正在运行
    bool IsRun();
    // 获取当前线程套接字数量
    int GetCount();
    //启动线程
    bool RunThread();
    //获取当前系统对象的引用
    CThreadObj& GetThreadObj();
    
private:
    // 清空当前线程中套接字,析构或者异常时候使用
    bool Clear();
    // 获取系统套接字总数
    static int GetTotal();

private:
    // 线程过程函数
    static DWORD  WorkItemFun(PVOID lParam);
    
};

具体实现见上传文件





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值