//in Trans-Level, do nothing.
	int st_clientNode_baseTrans::deal_current_message_block()
	{
		//First, get uuid as soon as possible
		if (m_bUUIDRecieved==false)
		{
			if (bIsValidUserId( m_currentHeader.source_id) )
			{
				m_bUUIDRecieved = true;
				m_uuid =  m_currentHeader.source_id;
				//regisit client node to hash-table;
				m_pClientTable->regisitClientUUID(this);
			}
			else if (m_currentHeader.source_id==0xffffffff)
			{
				//New clients
			}
			else //Invalid
			{
				emit evt_Message(this,tr("Client ID is invalid! Close client immediatly."));
				m_currentBlock = QByteArray();
				emit evt_close_client(this->sock());
			}
		}
		else
		{
			if (!( bIsValidUserId(m_currentHeader.source_id)
				  ||
				  (m_currentHeader.source_id==0xffffffff)
				  )
					)
			{
				emit evt_Message(this,tr("Client ID is invalid! Close client immediatly."));
				m_currentBlock = QByteArray();
				emit evt_close_client(this->sock());
			}
			if (bIsValidUserId(m_currentHeader.source_id)==true &&
					m_uuid != m_currentHeader.source_id)
			{
				emit evt_Message(this,tr("Client ID Changed in Runtime! Close client immediatly."));
				m_currentBlock = QByteArray();
				emit evt_close_client(this->sock());
			}


		}

		return 0;
	}
Exemplo n.º 2
0
	/**
	 * @brief Begin a listening socket at special address and port. The socket will be activated as soon as possible
	 * The Wait-and-Accept approaches are all managed by Listening thread, instead of main-GUI thread.
	 * @fn zp_net_Engine::AddListeningAddress
	 * @param id The name of this listening address:port. You can later using RemoveListeningAddress(id) to close it.
	 * @param address Listening address. IPV6 is now not tested.
	 * @param nPort Listening Port. in Linux, this value should larger than 1024.
	 * @param bSSLConn True means this address using OpenSSL . False means plain TCP
	 */
	void zp_net_Engine::AddListeningAddress(QString  id,const QHostAddress & address , quint16 nPort,bool bSSLConn /*= true*/)
	{
		if (m_map_netListenThreads.find(id)==m_map_netListenThreads.end())
		{
			//Start Thread
			QThread * pThread = new QThread(this);
			zp_netListenThread * pListenObj = new zp_netListenThread(id,address,nPort,bSSLConn);
			pThread->start();
			//m_mutex_listen.lock();
			m_map_netInternalListenThreads[id] = pThread;
			m_map_netListenThreads[id] = pListenObj;
			//m_mutex_listen.unlock();
			//Bind Object to New thread
			connect(this,&zp_net_Engine::startListen,pListenObj,&zp_netListenThread::startListen,Qt::QueuedConnection);
			connect(this,&zp_net_Engine::stopListen,pListenObj,&zp_netListenThread::stopListen,Qt::QueuedConnection);
			connect(pListenObj,&zp_netListenThread::evt_Message,this,&zp_net_Engine::evt_Message,Qt::QueuedConnection);
			connect(pListenObj,&zp_netListenThread::evt_ListenClosed,this,&zp_net_Engine::on_ListenClosed,Qt::QueuedConnection);
			connect(pListenObj,&zp_netListenThread::evt_NewClientArrived,this,&zp_net_Engine::on_New_Arrived_Client,Qt::QueuedConnection);

			pListenObj->moveToThread(pThread);
			//Start Listen Immediately
			emit startListen(id);
		}
		else
			emit evt_Message(this,"Warning>"+QString(tr("This ID has been used.")));
	}
Exemplo n.º 3
0
	/**
	 * @brief This slot recieved incomming client socketDescriptor from listening threads.In this function, zp_net_Engine
	 * will make a balance control, choosing a trans-thread which currently holds least clients than others.
	 * @fn zp_net_Engine::on_New_Arrived_Client
	 * @param socketDescriptor the socket descriptor for incomming client.
	 */
	void zp_net_Engine::on_New_Arrived_Client(qintptr socketDescriptor)
	{
		zp_netListenThread * pSource = qobject_cast<zp_netListenThread *>(sender());
		if (!pSource)
		{
			emit evt_Message(this,"Warning>"+QString(tr("Non-zp_netListenThread type detected.")));
			return;
		}

		//emit evt_Message(this,"Info>" +  QString(tr("Incomming client arriverd.")));
		qDebug()<<tr("Incomming client arriverd.");

		int nsz = m_vec_NetTransThreads.size();
		int nMinPay = 0x7fffffff;
		int nMinIdx = -1;

		for (int i=0;i<nsz && nMinPay!=0;i++)
		{
			if (m_vec_NetTransThreads[i]->isActive()==false ||
					m_vec_NetTransThreads[i]->SSLConnection()!=pSource->bSSLConn()
					)
				continue;
			int nPat = m_vec_NetTransThreads[i]->CurrentClients();

			if (nPat<nMinPay)
			{
				nMinPay = nPat;
				nMinIdx = i;
			}
			//qDebug()<<i<<" "<<nPat<<" "<<nMinIdx;
		}
		//remove old threads
		for (int i=0;i<nsz;i++)
			if (m_vec_NetTransThreads[i]->isActive()==false )
				TransThreadDel(m_vec_NetTransThreads[i]);

		if (nMinIdx>=0 && nMinIdx<nsz)
			emit evt_EstablishConnection(m_vec_NetTransThreads[nMinIdx],socketDescriptor);
		else
		{
			emit evt_Message(this,"Warning>"+QString(tr("Need Trans Thread Object for clients.")));
			qCritical()<<tr("Need Trans Thread Object for clients.");
		}

	}
	void st_clientNode_baseTrans::CheckHeartBeating()
	{
		QDateTime dtm = QDateTime::currentDateTime();
		qint64 usc = this->m_last_Report.secsTo(dtm);
		if (usc >=m_pClientTable->heartBeatingThrd())
		{
			emit evt_Message(this,tr("Client ") + QString("%1").arg((unsigned int)((quint64)this)) + tr(" is dead, kick out."));
			emit evt_close_client(this->sock());
		}
	}
Exemplo n.º 5
0
	void zp_ClusterNode::CheckHeartBeating()
	{
		QDateTime dtm = QDateTime::currentDateTime();
		qint64 usc = this->m_last_Report.secsTo(dtm);
		int nThredHold = m_pTerm->heartBeatingThrdHold();
		if (usc >= nThredHold)
		{
			emit evt_Message(this,tr("Client ") + QString("%1").arg((unsigned int)((quint64)this)) + tr(" is dead, kick out."));
			emit evt_close_client(this->sock());
		}
	}
Exemplo n.º 6
0
	/**
	 * @brief Positive connect to a server.
	 * In p2p connection, when the other side opens a listening address, this object can directly connect to the remote side.
	 * @fn zp_net_Engine::connectTo
	 * @param address the address to connect to
	 * @param nPort port to connect to
	 * @param bSSLConn if true, SSL connections will be used
	 * @param extraData Extra data for users to remember extra imformation for this connection.this message will be
	 *        given back when on_connect is called.
	 * @return bool
	 */
	bool zp_net_Engine::connectTo (const QHostAddress & address , quint16 nPort,bool bSSLConn, quint64 extraData)
	{
		bool res= false;
		//m_mutex_trans.lock();
		int nsz = m_vec_NetTransThreads.size();
		int nMinPay = 0x7fffffff;
		int nMinIdx = -1;

		for (int i=0;i<nsz && nMinPay!=0;i++)
		{
			if (m_vec_NetTransThreads[i]->isActive()==false ||
					m_vec_NetTransThreads[i]->SSLConnection()!=bSSLConn
					)
				continue;
			int nPat = m_vec_NetTransThreads[i]->CurrentClients();

			if (nPat<nMinPay)
			{
				nMinPay = nPat;
				nMinIdx = i;
			}
			//qDebug()<<i<<" "<<nPat<<" "<<nMinIdx;
		}
		//remove old threads
		for (int i=0;i<nsz;i++)
			if (m_vec_NetTransThreads[i]->isActive()==false )
				TransThreadDel(m_vec_NetTransThreads[i]);

		if (nMinIdx>=0 && nMinIdx<nsz)
		{
			res = true;
			emit evt_FireConnection(m_vec_NetTransThreads[nMinIdx],address,nPort,extraData);
		}
		else
		{
			emit evt_Message(this,"Warning>"+QString(tr("Need Trans Thread Object for clients.")));
		}
		//m_mutex_trans.unlock();
		return res;
	}
Exemplo n.º 7
0
	//in Trans-Level, do nothing.
	int zp_ClusterNode::deal_current_message_block()
	{
		qint32 bytesLeft = m_currentHeader.data_length + sizeof(CROSS_SVR_MSG::tag_header)
				-m_currentMessageSize ;
		const CROSS_SVR_MSG * pMsg =(const CROSS_SVR_MSG *) m_currentBlock.constData();
		switch(m_currentHeader.messagetype)
		{
		case 0x00://Heart Beating
			if (bytesLeft==0)
			{
				m_nRemoteClientNums = pMsg->payload.heartBeating.nClients;
			}
			break;
		case 0x01://basicInfo, when connection established, this message should be used
//			UnComment code below, will generate debug output.
//			if (m_currentBlock.length()>=64)
//				emit evt_Message(this,"Debug:" + m_currentBlock.toHex().left(64) + "..." + m_currentBlock.toHex().right(64));
//			else
//				emit evt_Message(this,"Debug:" + m_currentBlock.toHex());

			if (bytesLeft==0)
			{
				QString strName ((const char *)pMsg->payload.basicInfo.name);
				if (strName != m_pTerm->name())
				{
					this->m_strTermName = strName;
					m_nPortLAN = pMsg->payload.basicInfo.port_LAN;
					m_addrLAN = QHostAddress((const char *)pMsg->payload.basicInfo.Address_LAN);
					m_nPortPub = pMsg->payload.basicInfo.port_Pub;
					m_addrPub = QHostAddress((const char *)pMsg->payload.basicInfo.Address_Pub);
					if (false==m_pTerm->regisitNewServer(this))
					{
						this->m_strTermName.clear();
						emit evt_Message(this,tr("Info: New Svr already regisited. Ignored.")+strName);
						emit evt_close_client(this->sock());
					}
					else
					{
						emit evt_NewSvrConnected(this->termName());
						m_pTerm->BroadcastServers();
					}
				}
				else
				{
					emit evt_Message(this,tr("Can not connect to it-self, Loopback connections is forbidden."));
					emit evt_close_client(this->sock());
				}
			}
			break;
		case 0x02: //Server - broadcast messages
//			UnComment code below, will generate debug output.
//			if (m_currentBlock.length()>=64)
//				emit evt_Message(this,"Debug:" + m_currentBlock.toHex().left(64) + "..." + m_currentBlock.toHex().right(64));
//			else
//				emit evt_Message(this,"Debug:" + m_currentBlock.toHex());

			if (bytesLeft==0)
			{
				int nSvrs = pMsg->hearder.data_length / sizeof(CROSS_SVR_MSG::uni_payload::tag_CSM_Broadcast);
				for (int i=0;i<nSvrs;i++)
				{
					QString strName ((const char *)pMsg->payload.broadcastMsg[i].name);
					if (strName != m_pTerm->name() && m_pTerm->SvrNodeFromName(strName)==NULL)
					{
						QHostAddress addrToConnectTo((const char *)pMsg->payload.broadcastMsg[i].Address_LAN);
						quint16 PortToConnectTo = pMsg->payload.broadcastMsg[i].port_LAN;
						//because cross-connection is not good, we just want the low Addr:port connect to max Addr:Port.
						//Connect to New Servers
						if (strName > m_pTerm->name())
							emit evt_connect_to(addrToConnectTo,PortToConnectTo,false);
						else
							emit evt_Message(this,tr("Name %1 <= %2, omitted.").arg(strName).arg(m_pTerm->name()));
					}
				}
			}
			break;
		case 0x03:
			//			UnComment code below, will generate debug output.
//			if (m_currentBlock.length()>=64)
//				emit evt_Message(this,"Debug:" + m_currentBlock.toHex().left(64) + "..." + m_currentBlock.toHex().right(64));
//			else
//				emit evt_Message(this,"Debug:" + m_currentBlock.toHex());

			if (m_currentMessageSize==m_currentBlock.size())
			{
				QByteArray arraySend ((const char *)(pMsg) + sizeof(CROSS_SVR_MSG::tag_header),
									  m_currentMessageSize - sizeof(CROSS_SVR_MSG::tag_header));
				if (deal_user_data(arraySend)==true)
					m_currentBlock = QByteArray();
			}
			else
			{
				if (deal_user_data(m_currentBlock)==true)
					m_currentBlock = QByteArray();
			}
			break;
		default:
			emit evt_Message(this,tr("Info:Unknown Msg Type got."));
			emit evt_close_client(this->sock());
			break;
		};

		return 0;
	}
Exemplo n.º 8
0
	//!deal one message, affect m_currentRedOffset,m_currentMessageSize,m_currentHeader
	//!return bytes Used.
	int zp_ClusterNode::filter_message(QByteArray  block, int offset)
	{
		const int blocklen = block.length();
		while (blocklen>offset)
		{
			const char * dataptr = block.constData();

			//Recieve First 2 byte
			while (m_currentMessageSize<2 && blocklen>offset )
			{
				m_currentBlock.push_back(dataptr[offset++]);
				m_currentMessageSize++;
			}
			if (m_currentMessageSize < 2) //First 2 byte not complete
				continue;

			if (m_currentMessageSize==2)
			{
				const char * headerptr = m_currentBlock.constData();
				memcpy((void *)&m_currentHeader,headerptr,2);
			}


			if (m_currentHeader.Mark == 0x1234)
				//Valid Message
			{
				//while (m_currentMessageSize< sizeof(CROSS_SVR_MSG::tag_header) && blocklen>offset)
				if (m_currentMessageSize< sizeof(CROSS_SVR_MSG::tag_header) && blocklen>offset)
				{
					int nCpy = sizeof(CROSS_SVR_MSG::tag_header) - m_currentMessageSize;
					if (nCpy > blocklen - offset)
						nCpy = blocklen - offset;
					QByteArray arrCpy(dataptr+offset,nCpy);
					m_currentBlock.push_back(arrCpy);
					//m_currentBlock.push_back(dataptr[offset++]);
					//m_currentMessageSize++;
					offset += nCpy;
					m_currentMessageSize += nCpy;
				}
				if (m_currentMessageSize < sizeof(CROSS_SVR_MSG::tag_header)) //Header not completed.
					continue;
				else if (m_currentMessageSize == sizeof(CROSS_SVR_MSG::tag_header))//Header just  completed.
				{
					const char * headerptr = m_currentBlock.constData();
					memcpy((void *)&m_currentHeader,headerptr,sizeof(CROSS_SVR_MSG::tag_header));

					//continue reading if there is data left behind
					if (block.length()>offset)
					{
						qint32 bitLeft = m_currentHeader.data_length + sizeof(CROSS_SVR_MSG::tag_header)
								-m_currentMessageSize ;
						//while (bitLeft>0 && blocklen>offset)
						if (bitLeft>0 && blocklen>offset)
						{
							int nCpy = bitLeft;
							if (nCpy > blocklen - offset)
								nCpy = blocklen - offset;
							QByteArray arrCpy(dataptr+offset,nCpy);
							m_currentBlock.push_back(arrCpy);
							offset += nCpy;
							m_currentMessageSize += nCpy;
							bitLeft -= nCpy;
							//m_currentBlock.push_back(dataptr[offset++]);
							//m_currentMessageSize++;
							//bitLeft--;
						}
						//deal block, may be send data as soon as possible;
						deal_current_message_block();
						if (bitLeft>0)
							continue;
						//This Message is Over. Start a new one.
						m_currentMessageSize = 0;
						m_currentBlock = QByteArray();
						continue;
					}
				}
				else
				{
					if (block.length()>offset)
					{
						qint32 bitLeft = m_currentHeader.data_length + sizeof(CROSS_SVR_MSG::tag_header)
								-m_currentMessageSize ;
						//while (bitLeft>0 && blocklen>offset)
						if (bitLeft>0 && blocklen>offset)
						{
							int nCpy = bitLeft;
							if (nCpy > blocklen - offset)
								nCpy = blocklen - offset;
							QByteArray arrCpy(dataptr+offset,nCpy);
							m_currentBlock.push_back(arrCpy);
							offset += nCpy;
							m_currentMessageSize += nCpy;
							bitLeft -= nCpy;

							//m_currentBlock.push_back(dataptr[offset++]);
							//m_currentMessageSize++;
							//bitLeft--;
						}
						//deal block, may be processed as soon as possible;
						deal_current_message_block();
						if (bitLeft>0)
							continue;
						//This Message is Over. Start a new one.
						m_currentMessageSize = 0;
						m_currentBlock = QByteArray();
						continue;
					}
				} // end if there is more bytes to append
			} //end deal trans message
			else
			{
				const char * ptrCurrData = m_currentBlock.constData();
				emit evt_Message(this,tr("Client Send a unknown start Header %1 %2. Close client immediately.")
								 .arg((int)(ptrCurrData[0])).arg((int)(ptrCurrData[1])));
				m_currentMessageSize = 0;
				m_currentBlock = QByteArray();
				offset = blocklen;
				emit evt_close_client(this->sock());
			}
		} // end while block len > offset

		return offset;
	}
	//!deal one message, affect m_currentRedOffset,m_currentMessageSize,m_currentHeader
	//!return bytes Used.
	int st_clientNode_baseTrans::filter_message(QByteArray  block, int offset)
	{
		const int blocklen = block.length();
		while (blocklen>offset)
		{
			const char * dataptr = block.constData();

			//Recieve First 2 byte
			while (m_currentMessageSize<2 && blocklen>offset )
			{
				m_currentBlock.push_back(dataptr[offset++]);
				m_currentMessageSize++;
			}
			if (m_currentMessageSize < 2) //First 2 byte not complete
				continue;

			if (m_currentMessageSize==2)
			{
				const char * headerptr = m_currentBlock.constData();
				memcpy((void *)&m_currentHeader,headerptr,2);
			}


			//Heart Beating
			if (m_currentHeader.Mark == 0xBEBE)
			{
				if (m_currentMessageSize< sizeof(EXAMPLE_HEARTBEATING) && blocklen>offset )
				{
					int nCpy = offset - blocklen;
					if (nCpy > sizeof(EXAMPLE_HEARTBEATING) - m_currentMessageSize)
						nCpy =  sizeof(EXAMPLE_HEARTBEATING) - m_currentMessageSize;
					m_currentBlock.push_back(QByteArray(dataptr+offset,nCpy));
					offset += nCpy;
					m_currentMessageSize+=nCpy;
				}
				if (m_currentMessageSize < sizeof(EXAMPLE_HEARTBEATING)) //Header not completed.
					continue;
				//Send back
				emit evt_SendDataToClient(this->sock(),m_currentBlock);
				//Try to Get UUID Immediately
				if (m_bUUIDRecieved==false)
				{
					EXAMPLE_HEARTBEATING * pHbMsg = (EXAMPLE_HEARTBEATING *)(m_currentBlock.constData());
					if (bIsValidUserId(pHbMsg->source_id))
					{
						m_bUUIDRecieved = true;
						m_uuid =  pHbMsg->source_id;
						//regisit client node to hash-table;
						m_pClientTable->regisitClientUUID(this);
					}
				}

				//This Message is Over. Start a new one.
				m_currentMessageSize = 0;
				m_currentBlock = QByteArray();
				continue;
			}
			else if (m_currentHeader.Mark == 0x55AA)
				//Trans Message
			{
				if (m_currentMessageSize< sizeof(EXAMPLE_TRANS_MSG)-1 && blocklen>offset)
				{
					int nCpy =  blocklen - offset;
					if (nCpy > sizeof(EXAMPLE_TRANS_MSG)-1 - m_currentMessageSize)
						nCpy =  sizeof(EXAMPLE_TRANS_MSG)-1 - m_currentMessageSize;
					m_currentBlock.push_back(QByteArray(dataptr+offset,nCpy));
					offset += nCpy;
					m_currentMessageSize+=nCpy;
				}
				if (m_currentMessageSize < sizeof(EXAMPLE_TRANS_MSG)-1) //Header not completed.
					continue;
				else if (m_currentMessageSize == sizeof(EXAMPLE_TRANS_MSG)-1)//Header just  completed.
				{
					const char * headerptr = m_currentBlock.constData();
					memcpy((void *)&m_currentHeader,headerptr,sizeof(EXAMPLE_TRANS_MSG)-1);

					//continue reading if there is data left behind
					if (block.length()>offset)
					{
						qint32 bitLeft = m_currentHeader.data_length + sizeof(EXAMPLE_TRANS_MSG) - 1
								-m_currentMessageSize ;
						if (bitLeft>0 && blocklen>offset)
						{
							int nCpy =  blocklen - offset;
							if (nCpy > bitLeft)
								nCpy =  bitLeft;
							m_currentBlock.push_back(QByteArray(dataptr+offset,nCpy));
							offset += nCpy;
							m_currentMessageSize+=nCpy;
							bitLeft -= nCpy;
						}
						//deal block, may be send data as soon as possible;
						deal_current_message_block();
						if (bitLeft>0)
							continue;
						//This Message is Over. Start a new one.
						m_currentMessageSize = 0;
						m_currentBlock = QByteArray();
						continue;
					}
				}
				else
				{
					if (block.length()>offset)
					{
						qint32 bitLeft = m_currentHeader.data_length + sizeof(EXAMPLE_TRANS_MSG) - 1
								-m_currentMessageSize ;
						if (bitLeft>0 && blocklen>offset)
						{
							int nCpy =  blocklen - offset;
							if (nCpy > bitLeft)
								nCpy =  bitLeft;
							m_currentBlock.push_back(QByteArray(dataptr+offset,nCpy));
							offset += nCpy;
							m_currentMessageSize+=nCpy;
							bitLeft -= nCpy;
						}
						//deal block, may be processed as soon as possible;
						deal_current_message_block();
						if (bitLeft>0)
							continue;
						//This Message is Over. Start a new one.
						m_currentMessageSize = 0;
						m_currentBlock = QByteArray();
						continue;
					}
				} // end if there is more bytes to append
			} //end deal trans message
			else
			{
				const char * ptrCurrData = m_currentBlock.constData();
				emit evt_Message(this,tr("Client Send a unknown start Header %1 %2. Close client immediately.")
								 .arg((int)(ptrCurrData[0])).arg((int)(ptrCurrData[1])));
				m_currentMessageSize = 0;
				m_currentBlock = QByteArray();
				offset = blocklen;
				emit evt_close_client(this->sock());
			}
		} // end while block len > offset

		return offset;
	}