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