socket 服务端类模块封装

1. Server.h

#ifndef SOCKET_SERVER_H
#define SOCKET_SERVER_H

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h> 
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <execinfo.h>
#include <signal.h>
#include "./Typedef.h"
#include "Print.h"

#define SOCKET_BUFFER		2048

#define INADDR_ANY ((in_addr_t) 0x00000000)

#define THRD_FLAG_FREE		0	//线程空闲
#define THRD_FLAG_USAGE		1	//线程使用
#define THRD_FLAG_EXITING	2	//线程等待退出

//Socket参数 + 线程参数
typedef struct {
	BYTE bFlag; //线程状态标志
	pthread_attr_t att; //线程属性
	pthread_t tThrd; //线程句柄
	
	int iFd; //socket句柄
	struct sockaddr_in addr; //socket信息(地址+端口)
	socklen_t addrLen; //socket信息长度(地址+端口)
}TSktThrdPara;

	
class CServer{
private:
	CPrint *m_pCPrint;
	TSktThrdPara m_TSrvPara;
	TSktThrdPara *m_pTCltPara=NULL;
	DWORD m_dwSrvIP;
	DWORD m_dwSrvPort;
	DWORD m_dwConnectClients;
	int m_iCurIdx;
	
	TSktThrdPara *GetSktThrdPara();
	
	void UpdSktThrdPara(TSktThrdPara *pTSktThrdPara, BYTE bFlag);

	void CltFunc();

	void SrvFunc();
	
	static void *CltThrd(void *pvData); 
	
	static void *SrvThrd(void *pvData);

public:
	
	CServer();
	
	~CServer();
	
	bool InitSrv(DWORD dwSrvIP, DWORD dwPort, DWORD dwConnectClients);
	
	bool CloseSrv();
	
	virtual int ProcSrv(BYTE *pbRxBuf, int iRxLen, BYTE *pbTxBuf, int iTxLen){return -1;};
	
};

#endif //SOCKET_SERVER_H

2. Server.cpp

#include "SocketServer.h"

CServer::CServer()
{
	m_pCPrint = new CPrint();
	memset((BYTE*)&m_TSrvPara, 0, sizeof(m_TSrvPara));
}

CServer::~CServer()
{
	delete m_pCPrint;
}

TSktThrdPara *CServer::GetSktThrdPara()
{
	int idx;
	
	for (idx=0; idx<m_dwConnectClients; idx++)
	{
		if (&m_pTCltPara[idx] != NULL)
		{
			if (m_pTCltPara[idx].bFlag == THRD_FLAG_EXITING)
				m_pTCltPara[idx].bFlag = THRD_FLAG_FREE;
			
			if (m_pTCltPara[idx].bFlag == THRD_FLAG_FREE)
			{
				m_iCurIdx = idx;
				return &m_pTCltPara[idx];
			}
		}
	}
	
	return NULL;
}

void CServer::UpdSktThrdPara(TSktThrdPara *pTSktThrdPara, BYTE bFlag)
{
	pTSktThrdPara->bFlag = bFlag;
}

void *CServer::CltThrd(void *pvData)
{
	((CServer*)pvData)->CltFunc();
}

void *CServer::SrvThrd(void *pvData)
{
	((CServer*)pvData)->SrvFunc();
}

void CServer::CltFunc()
{
	TSktThrdPara *pSktThrdPara = &this->m_pTCltPara[this->m_iCurIdx];
	BYTE bRxBuf[SOCKET_BUFFER], bTxBuf[SOCKET_BUFFER];
	int iRet;
	
	m_pCPrint->PrintStr("CltThrd start: iCltFd=%d.\n", pSktThrdPara->iFd);

	while (1)
	{
		memset(bRxBuf, 0, sizeof(bRxBuf));
		if ((iRet=recv(pSktThrdPara->iFd, bRxBuf, sizeof(bRxBuf), 0)) > 0)
		{
			memset(bTxBuf, 0, sizeof(bTxBuf));
			if ((iRet=ProcSrv(bRxBuf, iRet, bTxBuf, sizeof(bTxBuf))) > 0)
			{
				if ((iRet=send(pSktThrdPara->iFd, bTxBuf, iRet, 0)) < 0)
					m_pCPrint->PrintStr("CltThrd(fd=%d):send \n", pSktThrdPara->iFd, strerror(iRet));
			}
		}
		else if (iRet == 0)
		{
			break;
		}
	}
	
	UpdSktThrdPara(pSktThrdPara, THRD_FLAG_EXITING);
	close(pSktThrdPara->iFd);
}

void CServer::SrvFunc()
{
	CServer *pCSrv = (CServer *)this;
	TSktThrdPara *pSrvPara = &(pCSrv->m_TSrvPara);
	TSktThrdPara *pSktThrdPara;
	
	m_pCPrint->PrintStr("SrvThrd start: iSrvFd=%d.\n", pSrvPara->iFd);
	
	while (1)
	{
		if ((pSktThrdPara=pCSrv->GetSktThrdPara()) != NULL)
		{
			pSktThrdPara->addrLen = sizeof(pSktThrdPara->addr);
			pSktThrdPara->iFd = accept(pSrvPara->iFd, (struct sockaddr*)&pSktThrdPara->addr, &pSktThrdPara->addrLen);
			if (pSktThrdPara->iFd > 0)
			{
				pthread_attr_init(&pSktThrdPara->att);
				pthread_attr_setdetachstate(&pSktThrdPara->att,  PTHREAD_CREATE_DETACHED); //设置线程属性,线程退出时自动回收资源
				pthread_create(&pSktThrdPara->tThrd, &pSktThrdPara->att, CltThrd, pSktThrdPara);	
			}
			else
			{
				m_pCPrint->PrintStr("SrvThrd:accept %s\n", strerror(pSktThrdPara->iFd));
			}
		}
		usleep(100*1000);
	}
}


bool CServer::InitSrv(DWORD dwSrvIP, DWORD dwPort, DWORD dwConnectClients)
{
	int iRet;
	
	m_dwSrvIP = dwSrvIP;
	m_dwSrvPort = dwPort;
	m_dwConnectClients = dwConnectClients;
	
	if((m_TSrvPara.iFd=socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
		m_pCPrint->PrintStr("InitSrv:socket %s", strerror(m_TSrvPara.iFd));
        return false;
    }  

	m_TSrvPara.addr.sin_family = AF_INET;
	m_TSrvPara.addr.sin_addr.s_addr = (m_dwSrvIP==0)? htonl(INADDR_ANY) : htonl(m_dwSrvIP);
    m_TSrvPara.addr.sin_port = m_dwSrvPort;
	m_TSrvPara.addrLen=sizeof(m_TSrvPara.addr);
	if ((iRet=bind(m_TSrvPara.iFd, (struct sockaddr *)&m_TSrvPara.addr, m_TSrvPara.addrLen)) < 0)
	{
		m_pCPrint->PrintStr("InitSrv:bind %s", strerror(iRet));
		close(m_TSrvPara.iFd);
		return false;
	}

	if((listen(m_TSrvPara.iFd, m_dwConnectClients)) < 0)
    {
		m_pCPrint->PrintStr("InitSrv:listen %s", strerror(iRet));
        close(m_TSrvPara.iFd);
        return false;
    }
	
	m_pTCltPara = new TSktThrdPara[m_dwConnectClients];

	pthread_attr_init(&m_TSrvPara.att);
	pthread_attr_setdetachstate(&m_TSrvPara.att, PTHREAD_CREATE_DETACHED); //设置线程属性,线程退出时自动回收资源
	pthread_create(&m_TSrvPara.tThrd, &m_TSrvPara.att, SrvThrd, (void*)this); //创建服务端线程	
	
	return true;
}

bool CServer::CloseSrv()
{
	bool fRet = true;
	
	if (m_TSrvPara.iFd > 0)
	{
		fRet = close(m_TSrvPara.iFd);
		m_TSrvPara.iFd = 0;
	}
	
	if (m_pTCltPara != NULL)
		delete[] m_pTCltPara; 

	return fRet;
}

3. 使用

#由于该接口类实现了去耦,其它模块在调用时通过继承该类即可,然后重写虚函数ProcSrv()即可。。。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值