NetworkMessage* NetworkMessage::DeserializePacket( OS::StreamReader& s)
	{
		byte d[4];
		s.read(d, 4);
		NetworkMessageType v=(NetworkMessageType)core::BitConverter::ToUInt32(d);
		NetworkMessage* ret = 0;
		switch (v)
		{
		case NetworkMessageType::SpeedChange:
			ret = new SpeedChangeMessage();
			break;
		case NetworkMessageType::HeadChange:
			ret = new HeadChangeMessage();
			break;
		case NetworkMessageType::Stop:
			ret = new StopMessage();
			break;
		case NetworkMessageType::VideoImage:
			ret = new VideoImageMessage();
			break;
		}
		if (ret != 0)
			if(!ret->Deserialize(s))
			{
				delete ret;
				ret=0;
			}
		return ret;
	}
	void TcpConnectionHandler::HandleReceiveMsgAndConns()
	{
		// https://www.ibm.com/support/knowledgecenter/en/ssw_i5_54/rzab6/poll.htm
		std::vector<pollfd> poll_fds;
		pollfd master_fd;
		master_fd.fd = m_listenerPtr->m_socket->GetNativeSocket();
		master_fd.events = POLLRDNORM;
		poll_fds.emplace_back(master_fd);

		int res = poll(poll_fds.data(), poll_fds.size(), -1);

		if (res < 0)
		{
			//poll error
		}

		//should never timeout because its infinite (negative)
		//if (res == 0)
		//{
			//timeout
		//}

		for (int i = 0; i < poll_fds.size(); i++)
		{
			if (poll_fds.at(i).revents == 0)
				continue;

			if (poll_fds[i].revents != POLLRDNORM)
			{
				printf("  Error! revents = %d\n", poll_fds.at(i).revents);
				//end_server = TRUE;
				break;

			}
			if (poll_fds.at(i).fd == m_listenerPtr->m_socket->GetNativeSocket())
			{
				TcpClient *c = m_listenerPtr->AcceptClient();
				if (c)
				{
					std::shared_ptr<TcpConnection> connection = std::make_shared<TcpConnection>(c);

					pollfd new_client;
					new_client.fd = connection->GetClient()->m_socket->GetNativeSocket();
					new_client.events = POLLRDNORM;
					poll_fds.emplace_back(new_client);

					AddClient(connection);
				}
			}
			else // not the listening socket
			{
				SOCKET c = poll_fds.at(i).fd;
				std::unique_ptr<uint8_t> header(new uint8_t[sizeof(NetworkHeader*)]());

				int32_t read;
				if ((read = recv(c, (char*)header.get(), sizeof(NetworkHeader*), 0)) != sizeof(NetworkHeader*))
					continue;

				std::unique_ptr<NetworkHeader> net_header((NetworkHeader*)header.get());
				std::unique_ptr<uint8_t> buffer(new uint8_t[net_header->Size]());

				if ((read = recv(c, (char*)buffer.get(), net_header->Size, 0)) == net_header->Size)
				{
					NetworkMessage msg;
					msg.Deserialize(buffer.get(), net_header->Size);

					if (msg.GetTag() == (uint32_t)InternalTags::Disconnect)
						m_queue->EnqueueDisconnection(msg);
					else if (msg.GetTag() == (uint32_t)InternalTags::Connect)
						m_queue->EnqueueConnection(msg);
					else
						m_queue->EnqueueMessageReceived(msg);
				}
				else
					continue;
			}
		}
	}