⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsocket.cpp

📁 BCB下的高效开发包。包含大并发的网络库
💻 CPP
字号:
#include "QSocket.h"
#include "../QStdlib/QStdlib.h"
#include "../QSystem/QSystem.h"
//Winsock2声明
#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
#endif
#include "winsock2.h"
#include "Windows.h"
#include <algorithm>
//---------------------------------------------------------------------------
QBaseSocket::QBaseSocket()
    : m_Handle(INVALID_SOCKET)
    , m_OutTime(DEFAULT_OUTTIME)
{
}
QBaseSocket::~QBaseSocket()
{
	this->Close();
}
//---------------------------------------------------------------------------
void QBaseSocket::Reset(int SocketHandle)
{
	this->Close();
	m_Handle = SocketHandle;
}
//---------------------------------------------------------------------------
void QBaseSocket::Close()
{
	_QClose(m_Handle);
        m_Handle = INVALID_SOCKET;
}
//---------------------------------------------------------------------------
void QBaseSocket::SetBlock(bool Block)const
{
    _QSetBlock(m_Handle,Block);
}

bool QBaseSocket::WaitIn(int MSec)const//毫秒
{
	//-1:err,0:OutOfTime,1:ActionCome;
	TIMEVAL timeout;
	FD_SET mask;
	timeout.tv_usec = MSec % 1000 *1000;//是毫秒转换到微秒
	timeout.tv_sec = ( MSec / 1000);//usec微秒,sec秒
	FD_ZERO(&mask);
	FD_SET((UINT)m_Handle,&mask);
	if(MSec == -1)
		return 1==select(0,&mask,NULL,NULL,NULL);//为-1就使用永不超时
	return 1==select(0,&mask,NULL,NULL,&timeout);//为0立即超时
}
bool QBaseSocket::WaitOut(int MSec)const//毫秒
{
	//-1:err,0:OutOfTime,1:ActionCome;
	TIMEVAL timeout;
	FD_SET mask;
	timeout.tv_usec = MSec % 1000 *1000;//是毫秒转换到微秒
	timeout.tv_sec = ( MSec / 1000);//usec微秒,sec秒
	FD_ZERO(&mask);
	FD_SET((UINT)m_Handle,&mask);
	if(MSec == -1)
		return select(0,NULL,&mask,NULL,NULL);//为-1就使用永不超时
	return select(0,NULL,&mask,NULL,&timeout);//为0立即超
}
bool QBaseSocket::WaitInOut(int MSec)const//毫秒
{
	//-1:err,0:OutOfTime,1:ActionCome;
	TIMEVAL timeout;
	FD_SET mask;
	timeout.tv_usec = MSec % 1000 *1000;//是毫秒转换到微秒
	timeout.tv_sec = ( MSec / 1000);//usec微秒,sec秒
	FD_ZERO(&mask);
	FD_SET((UINT)m_Handle,&mask);
	if(MSec == -1)
		return 1==select(0,&mask,&mask,NULL,NULL);//为-1就使用永不超时
	return 1==select(0,&mask,&mask,NULL,&timeout);//为0立即超
}
QConn QBaseSocket::GetRemote()const
{
        return _QGetRemote(m_Handle);
}
QConn QBaseSocket::GetLocal()const
{
        return _QGetLocal(m_Handle);
}
int QBaseSocket::GetHandle()const {return m_Handle;}
void QBaseSocket::SetOutTime(int Ms) {m_OutTime=Ms;}
int QBaseSocket::GetOutTime()const {return m_OutTime;}
//---------------------------------------------------------------------------
const std::string QCustomSocket::PackageSeg::HeadSign="<QHEAD>";
QCustomSocket::QCustomSocket()
{
	this->SetRecvSafeTimeOut();
}
unsigned int QCustomSocket::GetRecvSafeTimeOut(void)
{
	return m_RecvSafeTimeOut;
}
bool QCustomSocket::Send(const std::string &Data,int *pSended)const
{
        if (!pSended)
                return false;
        return _QSend(m_Handle, Data, pSended);
}
bool QCustomSocket::Send(const std::string &Data)const
{
        int Sended = 0;//忽略
        return _QSend(m_Handle, Data, &Sended);
}
bool QCustomSocket::SendPackage(const std::string &Data)const
{
        if(!Send(PackageSeg::HeadSign))
                return false;
        const unsigned int Size = Data.size();
        std::string SizeOfStr((const char*)&Size,sizeof(Size));//在头部发送数据包长度信息
        if(!Send(SizeOfStr))
                return false;
	return Send(Data);
}
bool QCustomSocket::Recv(std::string* pData,unsigned int GetLen)const
{
        if (!pData)
                return false;
	if(!this->WaitIn(m_OutTime))
		return false;
        return _QRecv(m_Handle, pData, GetLen);
}
void QCustomSocket::SetRecvSafeTimeOut(unsigned int Max)
{  	m_RecvSafeTimeOut=Max;
}
bool QCustomSocket::RecvSeg(std::string* pData, const std::string &EndSign
    ,unsigned int Max)const
{
	unsigned int StartTime = GetTickCount();
	Max+=EndSign.size();
 	pData->clear();
        if(EndSign.empty())
                return true;
        char Bit;
        while(true) {
                if(GetRealTickDifference(StartTime, GetTickCount()) > (UINT)m_RecvSafeTimeOut)
                        return false;
		if(!WaitIn(std::min(m_OutTime,m_RecvSafeTimeOut)))
			return false;
                int Ret = recv(m_Handle, &Bit, sizeof(Bit), 0);
                if(Ret <= 0) {
                        pData->clear();
                        return false;
                }
                pData->append(1, Bit);
                if(pData->size() > Max)
        	       return false;
                if(pData->size() >= EndSign.size()) {
                        std::string::iterator i = std::search(pData->end()-EndSign.size(), pData->end()
                            ,EndSign.begin(),EndSign.end());
                        if(i != pData->end()) {
                                pData->resize(pData->size() - EndSign.size());
                                return true;
                        }
                }
        }
}
bool QCustomSocket::RecvPackage(std::string* pData)
{
	unsigned int StartTime = GetTickCount();
 	std::string Data;
        if(!RecvSeg(&Data, PackageSeg::HeadSign, 32))//32个字节的模糊对齐,<QHEAD>前面可能有垃圾数据的意思,但不应该整体超过了32字节
		return false;
        unsigned int Len;
        if(!Recv(&Data, sizeof(Len)))
                return false;
        Len = *(unsigned int*)Data.data();

	if(!WaitIn(m_OutTime))
		return false;

	char buf[BUFFERMAX];
        pData->clear();
	pData->reserve(Len);
        unsigned int Last = Len;
        while(Last > 0) {
                if(GetRealTickDifference(StartTime, GetTickCount()) > (UINT)m_RecvSafeTimeOut) {
                        pData->clear();
                        return false;
                }
                if(!WaitIn(std::min(m_OutTime, m_RecvSafeTimeOut))) {
                        pData->clear();
                        return false;
                }
                int Ret = recv(m_Handle, buf,(sizeof(buf) < Last) ? sizeof(buf) : Last, 0);
                if(Ret <= 0) {
                        pData->clear();
                        return false;
                }
                Last -= Ret;
                pData->append(buf, Ret);
        }
        return true;
}
//---------------------------------------------------------------------------
bool QTcpClientSocket::Connect(const std::string& IpAddr, unsigned int Port,bool Block)
{
	this->Close();

	m_Handle = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(INVALID_SOCKET == m_Handle)
		return false;
	sockaddr_in service;
	service.sin_family=AF_INET;
	service.sin_addr.s_addr=inet_addr(IpAddr.c_str());
	service.sin_port = htons(static_cast<unsigned short>(Port));
	this->SetBlock(Block);
	if(0 != connect(m_Handle, (struct sockaddr*)&service, sizeof(service))) {//返回0是成功
                this->Close();
		return false;
	}
	return true;
}
//---------------------------------------------------------------------------
bool QTcpClientSocket::ConnectEx(const std::string& HostAddr,unsigned int Port,bool Block)
{
        std::string Ip = _QNameToIp(HostAddr);
        if(Ip.empty())
                Ip = HostAddr;
        return Connect(Ip, Port, Block);
}
//---------------------------------------------------------------------------
bool QTcpServerSocket::Bind(unsigned int Port)
{
	this->Close();
	m_Handle = _QCreateSocket();
        if(INVALID_SOCKET == m_Handle)
                return false;
        if(!_QBind(m_Handle, Port)) {
                this->Close();
                return false;
        }
	return true;
}
bool QTcpServerSocket::Accept(QCustomSocket* pCustomSocket)const
{
        if (!pCustomSocket)
                return false;
	if (!this->WaitIn(m_OutTime))
		return false;
	int Sh = accept(m_Handle, NULL, NULL);
        if(INVALID_SOCKET == Sh)
                return false;
        pCustomSocket->Reset(Sh);
        return true;
}
//TCP服务器
//---------------------------------------------------------------------------
QTcpServer::QTcpServer(){m_Active=false;m_StopCmd=false;}
bool QTcpServer::Active()const{return m_Active;}
QTcpServerSocket& QTcpServer::GetServer(){return m_Server;}
bool QTcpServer::Start(unsigned int Port)
{
	if(m_Active)
		return false;
	m_StopCmd=false;
	if(!m_Server.Bind(Port))
		return false;
	if(!NewThread((void*)_thListen, this))
		return false;
        return true;
}
void QTcpServer::Stop()
{
        m_StopCmd=true;
        m_Server.Close();
}
int __stdcall _thListen(void* lpObject)
{
	QTcpServer &Qs=*static_cast<QTcpServer*>(lpObject);
	Qs.m_Active=true;
        while(true) {
                if(Qs.m_StopCmd)
                        break;
                QTcpServer::CSClient* lpClient;
                try{
                	lpClient=new QTcpServer::CSClient;
                } catch(...) {
                	MsgBox("new QTcpServer::CSClient失败", "异常发生");
                 	Sleep(100);
                	continue;
                }
            	if(!Qs.m_Server.Accept(&lpClient->Client))
                {
                    delete lpClient;
                    continue;
                }
                lpClient->lpMainServer = &Qs;
                if(!Qs.ExecuteThread((void*)_th_Ac, lpClient)) {
                	MsgBox("ExecuteThread失败", "错误发生");
                        delete lpClient;
                        continue;
                }
        }
        Qs.m_Active=false;
        Qs.m_StopCmd=false;
        return 0;
}
bool QTcpServer::ExecuteThread(void* lpThread,void* lpParam)
{
	return(NewThread(lpThread,lpParam));
}
int __stdcall _th_Ac (void* lpCSClient)
{
        if (!lpCSClient) {
                MsgBox("监听线程lpCSClient是空指针", "错误发生");
                return 0;
        }
	QTcpServer::CSClient* lpMyCSClient = (QTcpServer::CSClient*)lpCSClient;
	lpMyCSClient->lpMainServer->ClientAccept(lpMyCSClient->Client);
        delete lpMyCSClient;
        return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -