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

📄 qnetbase.cpp

📁 BCB下的高效开发包。包含大并发的网络库
💻 CPP
字号:
//---------------------------------------------------------------------------
#include "QNetBase.h"
#include "../QSystem/QSystem.h"
#include "../QStdlib/QStdlib.h"
//Winsock2声明
#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
#endif
#include "winsock2.h"
#include "Windows.h"

#include <vector>
#include <algorithm>
//---------------------------------------------------------------------------
static const unsigned int RECV_BUF = 8 * 1024;
//---------------------------------------------------------------------------
//网卡初始器,全自动的,透明的
#define MAKEWORDPP(a, b) \
    ((WORD) (((BYTE) (a)) | (((WORD) ((BYTE) (b))) << 8)))

class _QInitSock
{
public:
	_QInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
	{
                    // 初始化WS2_32.dll
                WSADATA wsaData;
                WORD sockVersion = MAKEWORDPP(minorVer,majorVer);
                int ret = ::WSAStartup(sockVersion, &wsaData);
                if(ret != 0) {
                       // assert(!"网络初始失败.");
                       // MsgBox("网络初始失败.");
                }
               // MsgBox("SOCK INIT");
        }
	~_QInitSock()
	{
              //  MsgBox("SOCK EXIT");
                ::WSACleanup();
        }
};
static _QInitSock _s;
//---------------------------------------------------------------------------
void _QClose(int Handle)
{
	if(INVALID_SOCKET != Handle)
		closesocket(Handle);
}
void _QShutdown(int Handle)
{
	if(INVALID_SOCKET != Handle)
		shutdown(Handle, SD_BOTH);
}
//---------------------------------------------------------------------------
void _QSetBlock(int Handle,bool Block)
{
	u_long iMode = Block ? 0 : 1;//0 TO Block,1 TO NonBlock;
	ioctlsocket(Handle, FIONBIO, &iMode);
}
//---------------------------------------------------------------------------
int _QCreateSocket()
{
	return socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
}
//---------------------------------------------------------------------------
bool _QConnect(int Handle,const std::string &IpAddr,unsigned int Port, bool Block)
{
	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));
	_QSetBlock(Handle,Block);
	if(0!=connect(Handle,(struct sockaddr*)&service,sizeof(service)))
		return false;
	return true;
}
//---------------------------------------------------------------------------
bool _QSpBind(int Handle, unsigned int Port)
{
	sockaddr_in service;
	service.sin_family=AF_INET;
	service.sin_addr.s_addr=INADDR_ANY;
	service.sin_port = htons(static_cast<unsigned short>(Port));
	if(bind(Handle,(SOCKADDR*) &service,sizeof(service)) != 0)
		return false;
	return true;
}
//---------------------------------------------------------------------------
bool _QBind(int Handle,unsigned int Port)
{
        if(!_QSpBind(Handle,Port))
		return false;
	if(listen(Handle, SOMAXCONN)==SOCKET_ERROR)
		return false;
	return true;
}
//---------------------------------------------------------------------------
bool _QAccept(int Handle,int* NewSocket)
{
        if (!NewSocket)
                return false;
        *NewSocket=accept(Handle,NULL,NULL);
        if(INVALID_SOCKET == *NewSocket)
                return false;
        return true;
}
//---------------------------------------------------------------------------
bool _QSend(int Handle, std::string* Data)
{
        if (!Data)
                return false;
	int Sended = send(Handle, Data->data(), Data->size(), 0);
        if(SOCKET_ERROR == Sended || 0 == Sended)
                return false;
        Data->erase(0, Sended);
        //*Data = Data->substr(Sended, Data->size() - Sended);
	return true;
}
//---------------------------------------------------------------------------
bool _QSend(int Handle,const std::string& Data,int* lpSend)
{
        if (!lpSend)
                return false;
	*lpSend = send( Handle, Data.data(), Data.size(), 0 );
        if(SOCKET_ERROR == *lpSend || 0 == *lpSend )
                return false;
	return true;
}
//---------------------------------------------------------------------------
bool _QRecv(int Handle, std::string* Data)
{
        if (!Data)
                return false;
        char buf[RECV_BUF];
        int Ret = recv(Handle, buf, sizeof(buf), 0 );
        if (Ret <= 0)
                return false;
        std::string(buf, Ret).swap(*Data);
	return true;
}
//---------------------------------------------------------------------------
bool _QRecv(int Handle, std::string* Data, unsigned int MaxGet)
{
        if (!Data)
                return false;
        char buf[RECV_BUF];
        int Ret = recv(Handle, buf, std::min(MaxGet, sizeof(buf)), 0 );
        if (Ret <= 0)
                return false;
        std::string(buf, Ret).swap(*Data);
	return true;
}
//---------------------------------------------------------------------------
QConn _QGetRemote(int Handle)
{
	sockaddr_in sa;
	int salen = sizeof(sa);
	getpeername(Handle, (sockaddr FAR *)&sa, &salen);
	std::vector<char> Addr(32, '\0');
	strcpy(&Addr[0], inet_ntoa(sa.sin_addr));
	QConn cs;
        cs.IpAddr = &Addr[0];
	cs.Port   = ntohs(sa.sin_port);
	return cs;
}
//---------------------------------------------------------------------------
QConn _QGetLocal(int Handle)
{
	sockaddr_in sa;
	int salen = sizeof(sa);
	getsockname(Handle, (sockaddr FAR *)&sa, &salen);
        std::vector<char> Addr(32, '\0');
	strcpy(&Addr[0], inet_ntoa(sa.sin_addr));
	QConn cs;
        cs.IpAddr = &Addr[0];
	cs.Port   = ntohs(sa.sin_port);
	return cs;
}
//---------------------------------------------------------------------------
bool _QSetTimeOutIn(int Handle,int TimeOut)
{
        return SOCKET_ERROR != setsockopt(Handle, SOL_SOCKET, SO_RCVTIMEO
            , (char*)&TimeOut, sizeof(TimeOut));
}
//---------------------------------------------------------------------------
bool _QSetTimeOutOut(int Handle,int TimeOut)
{
        return SOCKET_ERROR != setsockopt(Handle, SOL_SOCKET, SO_SNDTIMEO
            , (char*)&TimeOut, sizeof(TimeOut));
}
//---------------------------------------------------------------------------
bool _QSetDontLinger(int Handle)
{
        BOOL bDontLinger = TRUE;
        return 0 == setsockopt(Handle,SOL_SOCKET,SO_DONTLINGER
            ,(const char*)&bDontLinger,sizeof(BOOL));
}
//---------------------------------------------------------------------------
bool _QSelect(FD_SET* Read,FD_SET* Write,FD_SET* Except,long WaitMSec)
{
        if (!Read || !Write || !Except)
                return false;
        //-1:err,0:OutOfTime,1:ActionCome;                      //仅err为false
	TIMEVAL timeout;
        TIMEVAL* lptime=&timeout;
	timeout.tv_usec=WaitMSec%1000*1000;                     //是毫秒转换到微秒
	timeout.tv_sec=(WaitMSec/1000);                         //usec微秒,sec秒
	if(-1 == WaitMSec)
		lptime=NULL;
	return SOCKET_ERROR != select(0, Read, Write, Except, lptime);//为0立即超时
}
//---------------------------------------------------------------------------
void _QSetRecvBufSize(int Handle,unsigned int Byte)
{
    setsockopt(Handle, SOL_SOCKET, SO_RCVBUF, (const char*)&Byte, sizeof(Byte));
}
//---------------------------------------------------------------------------
void _QSetSendBufSize(int Handle,unsigned int Byte)
{
    setsockopt(Handle, SOL_SOCKET, SO_SNDBUF, (const char*)&Byte, sizeof(Byte));
}
//---------------------------------------------------------------------------
bool _QWaitIn(int Handle, int MSec)//毫秒
{
	//-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)Handle,&mask);
	if(-1 == MSec)
		return 1 == select(0, &mask, NULL, NULL, NULL);//为-1就使用永不超时
	return 1 == select(0, &mask, NULL, NULL, &timeout);//为0立即超时
}
//---------------------------------------------------------------------------
bool _QWaitOut(int Handle, int MSec)//毫秒
{
	//-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)Handle,&mask);
	if(-1 == MSec)
		return select(0,NULL,&mask,NULL,NULL);//为-1就使用永不超时
	return select(0,NULL,&mask,NULL,&timeout);//为0立即超
}
//---------------------------------------------------------------------------
bool _QWaitInOut(int Handle, int MSec)//毫秒
{
	//-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)Handle,&mask);
	if(-1 == MSec)
		return 1==select(0,&mask,&mask,NULL,NULL);//为-1就使用永不超时
	return 1==select(0,&mask,&mask,NULL,&timeout);//为0立即超
}
//---------------------------------------------------------------------------
bool _QRecvSeg(int s, std::string* Data,const std::string &EndSign,DWORD Max,DWORD RecvSafeTimeOut)
{
	unsigned int StartTime = GetTickCount();
	Max += EndSign.size();
 	Data->clear();
	if(EndSign.empty())
                return true;
        char Bit;
        while(true) {
                if(GetRealTickDifference(StartTime, GetTickCount()) > RecvSafeTimeOut)
                        return false;
	        if(!_QWaitIn(s, RecvSafeTimeOut))
			return false;
                int Ret = recv(s, &Bit, sizeof(Bit), 0);
                if(Ret <= 0) {
                        Data->clear();
                        return false;
                }
                Data->append(1,Bit);
                if(Data->size()>Max)
                        return false;
                if(Data->size() >= EndSign.size()) {
        	        std::string::iterator i = std::search(Data->end()-EndSign.size(),Data->end()
                            ,EndSign.begin(),EndSign.end());
                        if(Data->end() != i) {
                                Data->resize(Data->size()-EndSign.size());
                                return true;
                        }
                }
        }
}
//============================================================================
bool Private_QSelect(FD_SET* Read, FD_SET* Write, FD_SET* Except, long WaitMSec)
{
        //-1:err,0:OutOfTime,1:ActionCome;                      //仅err为false
        TIMEVAL timeout;
        TIMEVAL* lptime = &timeout;
        timeout.tv_usec = WaitMSec % 1000 * 1000;                     //是毫秒转换到微秒
        timeout.tv_sec  = (WaitMSec / 1000);                         //usec微秒,sec秒
        if(-1 == WaitMSec)
                lptime = NULL;
	return SOCKET_ERROR != select(0, Read, Write, Except, lptime);//为0立即超时
}
//---------------------------------------------------------------------------
void _QSelectRead(const std::vector<int>& SourceSockets, std::vector<int>* pOutPut)
{
        if (!pOutPut)
                return;
        pOutPut->clear();
        for (unsigned int i = 0; i < SourceSockets.size(); i += FD_SETSIZE) {
                unsigned int Wid = (SourceSockets.size() < i + FD_SETSIZE)
                    ? SourceSockets.size() : i + FD_SETSIZE;
                fd_set f;
                f.fd_count=0;
                for(unsigned int k = i; k < Wid; ++k)
                        f.fd_array[f.fd_count++] = SourceSockets[k];
                Private_QSelect(&f, NULL, NULL, 0);
                pOutPut->insert(pOutPut->end(), f.fd_array, &f.fd_array[f.fd_count]);
        }
}
//---------------------------------------------------------------------------
void _QSelectWrite(const std::vector<int>& SourceSockets, std::vector<int>* pOutPut)
{
        if (!pOutPut)
                return;
        pOutPut->clear();
        for (unsigned int i = 0; i < SourceSockets.size(); i += FD_SETSIZE) {
                unsigned int Wid = (SourceSockets.size() < i + FD_SETSIZE)
                    ? SourceSockets.size() : i + FD_SETSIZE;
                fd_set f;
                f.fd_count=0;
                for(unsigned int k = i; k < Wid; ++k)
                        f.fd_array[f.fd_count++] = SourceSockets[k];
                Private_QSelect(NULL, &f, NULL, 0);
                pOutPut->insert(pOutPut->end(), f.fd_array, &f.fd_array[f.fd_count]);
        }
}
//---------------------------------------------------------------------------
void _QSelectExcept(const std::vector<int>& SourceSockets, std::vector<int>* pOutPut)
{
        if (!pOutPut)
                return;
        pOutPut->clear();
        for (unsigned int i = 0; i < SourceSockets.size(); i += FD_SETSIZE) {
                unsigned int Wid = (SourceSockets.size() < i + FD_SETSIZE)
                    ? SourceSockets.size() : i + FD_SETSIZE;
                fd_set f;
                f.fd_count=0;
                for(unsigned int k = i; k < Wid; ++k)
                        f.fd_array[f.fd_count++] = SourceSockets[k];
                Private_QSelect(NULL, NULL, &f, 0);
                pOutPut->insert(pOutPut->end(), f.fd_array, &f.fd_array[f.fd_count]);
        }
}
//---------------------------------------------------------------------------
std::string _QNameToIp(const std::string &HostName)
{
        in_addr addr;
	hostent *hp;
	hp = gethostbyname(HostName.c_str());
	if(NULL != hp) {
		memmove(&addr, hp->h_addr_list[0], 4);
		return std::string(inet_ntoa(addr));
	}
        return "";
}
//---------------------------------------------------------------------------
std::string _QIpToName(const std::string &Ip)
{
        DWORD addr;
	hostent *hp;
	if(INADDR_NONE != (addr = inet_addr(Ip.c_str()))) {
		hp=gethostbyaddr((char*)&addr, sizeof(addr), AF_INET);
		if (NULL != hp)
			return std::string(hp->h_name);
	}
    return "";
}
//---------------------------------------------------------------------------
std::string _QGetHostName()
{
        std::vector<char> Ret(255, '\0');
        if(0 == gethostname(&Ret[0],Ret.size()))
                return std::string(&Ret[0]);
        return "";
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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