📄 qsocket.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 + -