Пример #1
0
void IClient::handleBinary(ByteArray &piece, string &str, shared_ptr<Invoke> &invoke, size_t size)
{
	if (piece.getPosition() >= size)
		return;

	ByteArray *byteArray = nullptr;
	size_t position = piece.getPosition();
	size_t param_index = 0;

	//FIND WHICH PARAMETER IS BINARY
	for (size_t i = 0; i < invoke->size(); i++)
		if (invoke->at(i)->getType() == "ByteArray")
		{
			const ByteArray &ba = invoke->at(i)->referValue<ByteArray>();
		
			if (ba.size() < ba.capacity())
			{
				param_index = i;
				byteArray = (ByteArray*)&ba;

				break;
			}
		}

	//IF THERE'S NOT BINARY TYPE
	if(byteArray == nullptr)
		return;

	//CALCULATE SIZE
	size_t totalSize = byteArray->capacity();
	size_t leftSize = totalSize - byteArray->size();
	size_t writeSize = std::min(size - position, leftSize);

	//AND WRITES
	byteArray->insert
	(
		byteArray->end(), 
		piece.begin() + position, piece.begin() + (position + writeSize)
	);
	piece.setPosition( position + writeSize );

	// IF NOT FULFILLED, RETURNS
	if (byteArray->size() < byteArray->capacity())
		return;

	//IF LAST BINARY
	for(size_t i = param_index + 1; i < invoke->size(); i++)
		if(invoke->at(i)->getType() == "ByteArray")
			return;

	// SHIFTS
	_replyData(invoke);

	//IS LAST BINARY, THEN CLEAR
	invoke.reset();

	//IF BYTES ARE LEFT, CALL HANDLE_STRING
	handleString(piece, str, invoke, size);
}
Пример #2
0
int Work::handleMsg(unsigned short id, ByteArray &ba, int fd)
{
	cout<< "Protocol id: "<< id << endl;
	switch(id)
	{
		case 100://--login
			struct LoginRecvMsg loginRecv; 
			memset(&loginRecv, 0, sizeof(loginRecv));
			memcpy(&loginRecv, &ba.buf[ba.getPosition()], sizeof(loginRecv));
			
			cout<<"UserInfo: "<<loginRecv.userID<<"  "<<loginRecv.password<<endl;
			
			ba.plusPosition(sizeof(loginRecv));
			cout<<"position is: "<<ba.getPosition() << " available is: "<<ba.getBytesAvailable() << endl;
			
			verifyUserData(loginRecv, fd);
//			cout<< ba.readUTFBytes(100) << endl;
//			cout<< ba.readUTFBytes(100) << endl;
			break;
		case 200://--register
			struct RegRecvMsg RegRecv; 
			memset(&RegRecv, 0, sizeof(RegRecv));
			memcpy(&RegRecv, &ba.buf[ba.getPosition()], sizeof(RegRecv));
			
			cout<<"UserInfo: "<<RegRecv.userID<<"  "<<RegRecv.password<<endl;
			
			ba.plusPosition(sizeof(RegRecv));
			cout<<"position is: "<<ba.getPosition() << " available is: "<<ba.getBytesAvailable() << endl;
			
			verifyRegEvent(RegRecv, fd);
			break;
		case 300://--friend list
			struct FriendListRecvMsg friendListRecv;
			memset(&friendListRecv, 0, sizeof(friendListRecv));
			memcpy(&friendListRecv, &ba.buf[ba.getPosition()], sizeof(friendListRecv));
			cout<<"UserID: "<<friendListRecv.userID<<endl;
			ba.plusPosition(sizeof(FriendListRecvMsg));
			cout<<"position is: "<<ba.getPosition() << " available is: "<<ba.getBytesAvailable() << endl;
			
			sendFriendList(friendListRecv,fd);
				
			break;
		case 500://---message
			struct SendMessageRecvMsg recvMsg;
			memset(&recvMsg, 0, sizeof(recvMsg));
			memcpy(&recvMsg, &ba.buf[ba.getPosition()], ba.getBytesAvailable());
			cout<<"Send User ID: "<<recvMsg.senderUserID << " Recive User ID: "<<recvMsg.receiverUserID << " Message Info: "<<recvMsg.messageInfo<<endl;
			ba.plusPosition(ba.getBytesAvailable());
			cout<<"position is: "<<ba.getPosition() << " available is: "<<ba.getBytesAvailable() << endl;
			
			handleRecvMsgInfo(recvMsg, fd);
			break;	
		default:
			cout<<"Unkonwn Protocol " << id << endl; 
			break;
	}
	
	return 0;
}
Пример #3
0
void IClient::handleString(ByteArray &piece, string &str, shared_ptr<Invoke> &baInvoke, size_t size)
{
	static size_t CLOSED_PARENTHESIS = string("</invoke>").size();

	if (piece.getPosition() >= size)
		return;

	// LIST OF INVOKE MESSAGES
	list<shared_ptr<Invoke>> invokeList;

	// READ STRING
	string &pieceString = piece.read<string>();
	str.append(pieceString);

	WeakString wstr = str;
	vector<WeakString> &wstrArray = wstr.betweens("<invoke ", "</invoke>");

	for (size_t i = 0; i < wstrArray.size(); i++)
	{
		string &message = "<invoke " + wstrArray[i].str() + "</invoke>";

		shared_ptr<Invoke> invoke( new Invoke() );
		invoke->construct(make_shared<XML>(message));

		invokeList.push_back(invoke);
	}

	/*list<shared_ptr<Invoke>> invokeList;
	pair<size_t, size_t> posPair = {-1, -1};
	pair<size_t, size_t> sizePair = {0, 0};
	pair<size_t, size_t> indexPair = {0, 0};

	size_t endIndex = -1;

	while (true)
	{
		// FIND WORDS
		pair<size_t, size_t> myPair = 
		{
			str.find("<invoke ", indexPair.first),
			str.find("</invoke>", indexPair.second)
		};

		// COUNTS
		if (myPair.first != -1)
		{
			sizePair.first++;
			indexPair.first = myPair.first + string("<invoke ").size();
		}
		if (myPair.second != -1)
		{
			sizePair.second++;
			indexPair.second = myPair.second + string("</invoke>").size();
		}
		
		// IF AN INVOKE MESSAGE HAS FOUND
		if (sizePair.first == sizePair.second && sizePair.first != 0)
		{
			if (posPair.first == -1 && posPair.second == -1)
				posPair = myPair;
			else
				posPair.second = myPair.second;

			endIndex = posPair.second + string("</invoke>").size();

			WeakString wstr(str.data() + posPair.first, str.data() + endIndex);
			shared_ptr<XML> xml(new XML(wstr));
			shared_ptr<Invoke> invoke(new Invoke());

			invoke->construct(xml);

			cout << invoke->toXML()->toString() << endl;

			invokeList.push_back(invoke);

			posPair = { -1, -1 };
		}
		else if (myPair.first != -1 && posPair.first == -1)
			posPair.first = myPair.first;
	}*/

	//BASIC DATA
	/*list<shared_ptr<Invoke>> invokeList;
	unique_ptr<pair<size_t, size_t>> indexPair(nullptr);
	pair<size_t, size_t> sizePair = {0, 0};
	size_t startIndex = 0;
	size_t endIndex = 0;

	while (true)
	{
		//FIND WORDS
		pair<size_t, size_t> iPair = 
		{
			str.find("<invoke ", startIndex),
			str.find("</invoke>", endIndex)
		};

		//COUNTS
		if (iPair.first != -1) sizePair.first++;
		if (iPair.second != -1) sizePair.second++;

		//IF IT MEANS THE START,
		if (indexPair.get() != nullptr && sizePair.first == 0)
		{
			//SPECIFY THE STARTING INDEX
			indexPair.reset(new pair<size_t, size_t>(iPair.first, string::npos)); 
		}

		//FAILED TO FIND NOTHING
		if(iPair.first == string::npos || iPair.second == string::npos)
			break;

		//AN INVOKE HAS FOUND
		if(indexPair.get() != nullptr && sizePair.first == sizePair.second)
		{
			//INDEX
			size_t start = indexPair->first;
			size_t end = indexPair->second + string("</invoke>").size();

			//CONSTRUCT INVOKE
			shared_ptr<XML> xml(new XML(str.substr(start, end - start)));
			shared_ptr<Invoke> invoke(new Invoke());
			invoke->construct(xml);

			invokeList.push_back(invoke);

			//CLEAR CURRENT INEX PAIR
			endIndex = end;
			indexPair.reset(nullptr);
		}

		//ADJUST INDEX
		startIndex = (iPair.second == string::npos) ? 
			iPair.first + 1 : iPair.second + 1;
	}

	//ERASE USED CHARACTERS
	if (endIndex != string::npos)
		str = str.substr(endIndex);*/

	if (invokeList.empty() == true)
		return;

	/*str = str.substr(endIndex);
	cout << "#" << invokeList.size() << endl;*/

	// CUT USED STRING
	str = move(str.substr(str.rfind("</invoke>") + CLOSED_PARENTHESIS));

	//CALL REPLY_DATA
	auto last_it = --invokeList.end();
	for (auto it = invokeList.begin(); it != last_it; it++)
		_replyData(*it);
	
	//TEST WHETHER THE LAST CONTAINS BINARY DATA
	shared_ptr<Invoke> &lastInvoke = *last_it;
	for (size_t i = 0; i < lastInvoke->size(); i++)
	{
		//IF HAS, TO HANDLE_BINARY
		if (lastInvoke->at(i)->getType() == "ByteArray")
		{
			baInvoke = lastInvoke;

			piece.setPosition
			(
				piece.getPosition() - 
				(pieceString.size() - (pieceString.rfind("</invoke>") + CLOSED_PARENTHESIS))
			);

			//HANDLING LEFT BINARY PIECE
			handleBinary(piece, str, baInvoke, size);
			return;
		}
	}

	//ELSE, DOES NOT HAVE, CALL REPLY_DATA
	_replyData(lastInvoke);
}
Пример #4
0
/* -----------------------------------------------------------------------
	LISTEN MESSAGE
----------------------------------------------------------------------- */
void IWebClientBase::listen()
{
	shared_ptr<Invoke> binaryInvoke;

	// CLIENT ADDS MASK
	unsigned char mask = DIRECTION() == SERVER ? 128 : 0;

	while (true)
	{
		ByteArray piece;
		boost::system::error_code error;

		piece.assign(BUFFER_SIZE(), NULL);
		socket->read_some(boost::asio::buffer(piece), error);

		while (piece.getPosition() != piece.size())
		{
			if (error)
				return;

			// GET TYPE
			unsigned char typeHeader = piece.read<unsigned char>();
			if (piece.leftSize() == 0)
				continue;

			// GET SIZE TYPE
			unsigned char sizeHeader = piece.read<unsigned char>() - mask;
			if (piece.leftSize() == 0)
				continue;

			// GET SIZE
			size_t size = 125;
			if (sizeHeader == 126)
			{
				if (piece.leftSize() < sizeof(unsigned short))
					listenMoreBytes(piece, error);

				if (error)
					break;

				size = (size_t)piece.readReversely<unsigned short>();
			}
			else if (sizeHeader == 127)
			{
				if (piece.leftSize() < sizeof(unsigned long long))
					listenMoreBytes(piece, error);

				if (error)
					break;

				size = (size_t)piece.readReversely<unsigned long long>();
			}

			// GET DATA FOLLOWING TYPE
			if (typeHeader == (unsigned char)129)
				binaryInvoke = listenString(size, piece, error);
			else if (typeHeader == (unsigned char)130 && binaryInvoke != nullptr)
				listenBinary(size, piece, binaryInvoke, error);
			else
				break;
		}
	}
}
Пример #5
0
//多客户端拼包和粘包不知道怎么处理。以后解决。 
int Work::recvSocket(int fd)
{
	ByteArray ba;
	int ret = 0;
	
	int recvSize = -1; 
	unsigned int totalRecv = 0;
	
	do
	{
		recvSize = recv(fd, ba.buf, sizeof(ba.buf), 0);
		cout << "recvSize:: "<<recvSize<<endl;
		if(recvSize > 0)
		{	
			totalRecv += recvSize;
		}
		ba.setBytesAvailable(totalRecv);
		ba.setBufLen(totalRecv);
		
	}while(recvSize > 0);
	//假如消息是从头开始接收的
	//假如不足四个字节 则不知道怎么处理,所以先要缓存起来 
	cout<< "total::  "<<ba.getBufLen()<<endl;
	if(ba.getBufLen() >= 4)//取得消息头和消息长度 等于4的时候是空消息 
	{
		len = ba.readUnsignedShort();//取得长度 
		cout<<"len:: "<<len<<endl;
		head = ba.readUnsignedShort();//取得协议号
		cout<<"head:: "<<head<<endl;
		
		if( ba.getBufLen() >= len )//包含了至少一条完整的消息 
		{		
			cout<<"position is: "<<ba.getPosition() << " available is: "<<ba.getBytesAvailable() << endl;
			handleMsg(head, ba, fd);
		}
 
	}
			
	if(recvSize < 0)    
    {   
    	if(errno == EINTR)//还要继续再读 
		{
    		cout<<"ERRNO IS EINTR"<<endl;
    		ret = 1;
		}
		else if(errno == EAGAIN)
		{
			cout<<"ERRNO IS EINTR"<<endl;
			ret = 1;	
		}
		else
		{
			cout<<"socket listen failed ! " << strerror(errno) << endl;
       		ret = - 1; 
		}
    }    
    else if(recvSize == 0)//正常退出
    {   
		cout<<"socket closed failed ! " << strerror(errno) << endl;   
        ret = 0;
		      
    }
	else
	{
    	ret =  1;
	}   

	return ret;
}