// ---------------------
// Update
void Session::Update()
{
	char buffer[MAX_BUFFER_SIZE];

	// Send game information
	SendMessageTo(g_gameFloor.getGame()->PackAllTableInformation(buffer), buffer);

	// Send player information
	SendMessageTo(BuildPlayerInfo(buffer), buffer);
}
void Server::AddUDPClient()
{
	try
	{		
		//udpMutex.lock();
		auto clientsInfo = new sockaddr();
		char *rawMetadata;
		{
			std::unique_lock<std::mutex> lock(udpMutex);
			rawMetadata = ReceiveRawDataFrom(this->_udp_socket, clientsInfo)->data;
		}
		auto metadata = ExtractMetadataUDP(rawMetadata);
		
		if (IsACK(clientsInfo, metadata)/* || memcmp(rawMetadata, ACK, 3) == 0*/) return;
		std::cout << "not ACK" << std::endl;
		metadata->file = new std::fstream();
		try	{
			OpenFile(metadata->file, metadata->fileName);
		} catch (std::runtime_error e) {
			SendMessageTo(this->_udp_socket, e.what(), clientsInfo);
			throw;
		}

		if (metadata->requestFileSize)
		{
			auto fileSize = GetFileSize(metadata->file);
			SendMessageTo(this->_udp_socket, std::to_string(fileSize), clientsInfo);
		}
		//udpMutex.unlock();
		metadata->file->seekg(metadata->progress);
		metadata->packagesTillDrop = PACKAGES_TILL_DROP;
		metadata->addr = clientsInfo;
		metadata->delay = 100;
		metadata->currentDelay = 1000;

		auto pair = new std::pair<std::mutex*, UDPMetadata*>(new std::mutex(), metadata);
		this->udpClients.push_back(pair);
		auto new_thread = new std::thread(SendFile, pair);
		this->threads.push_back(new_thread);
		std::cout << "new thread created" << std::endl;
	}
	catch (std::runtime_error e)
	{
		//file not found
	}
}
Exemple #3
0
int CClientManager::PollThread( void* arg )
{
	CClientManager* pManager = (CClientManager*)arg;

	//start the poll server and bind to specific port.
	SOCKET socksrv = Socket( PF_INET, SOCK_DGRAM, 0 );

	SOCKADDR_IN srvaddr;
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons( 0 );
	srvaddr.sin_addr.s_addr = INADDR_ANY;
	Bind( socksrv, (SOCKADDR*)&srvaddr, sizeof(SOCKADDR_IN) );
	socklen_t len = sizeof(SOCKADDR_IN);
	getsockname( socksrv, (SOCKADDR*)&srvaddr, &len );

#ifdef _WIN32
	SetUdpBlock( socksrv );
#endif

	CMessageBase msg;
	msg.Init( NCM_POLLSERVER, CSessionAddr(), CSessionAddr(), ntohs(srvaddr.sin_port) );
	SOCKET sockbroad = Socket( PF_INET, SOCK_DGRAM, 0 );
//	msg.Broadcast( sockbroad, NCP_SERVER_PING_PORT );
	closesocket( sockbroad );
	pManager->DoPoll( socksrv, ntohs(srvaddr.sin_port) );

	while( true ){
		fd_set rfds;
		FD_ZERO( &rfds );
		FD_SET( socksrv, &rfds );
		int maxfds = socksrv + 1;

		TIMEVAL tmout;
		tmout.tv_sec = 30;
		tmout.tv_usec = 0;
		int nRet = Select( maxfds, &rfds, NULL, NULL, &tmout );

		if( nRet==0 ){	//select timeout, should I do a poll for the remote hosts?
			pManager->DoPoll( socksrv, ntohs(srvaddr.sin_port) );
		}else if( FD_ISSET(socksrv, &rfds) ){
			SOCKADDR_IN srcaddr;
			CMessageBase* pMsg = RecvMessageFrom<CMessageBase>( socksrv, srcaddr );
			if( pMsg==NULL )continue;	//ignore NULL message.

			CMessageTrash trash(pMsg);
			if( pMsg->IsAcking(NCM_POLLSERVER) ){			//the server is acking our poll
				pManager->OnAckPoll( pMsg );
			}else if( pMsg->GetMessage()==NCM_SERVERSTART ){	//the server is starting, poll the server
				CMessageBase msg;
				msg.Init( NCM_POLLSERVER, CSessionAddr(), CSessionAddr(), NCP_SERVER_PING_PORT );
				srcaddr.sin_port = htons( NCP_SERVER_PING_PORT );
				SendMessageTo( socksrv, &msg, srcaddr );
			}
		}
	}//end of while
	closesocket( socksrv );
	return 0;
}
Exemple #4
0
void CClientManager::ShutdownServer( IN_ADDR addrHost, bool bForward )
{
	CSocket sock;
	sock.Socket( SOCK_DGRAM );

	if( addrHost.s_addr==INADDR_ANY ){
		//send shutdown message to all the known host addresses
		CObjLocker<CClientManager> locker(this);
		set<IN_ADDR>::iterator pos;
		for( pos=m_HostAddrs.begin(); pos!=m_HostAddrs.end(); ++pos ){
			CMessageBase msg;
			msg.Init( NCM_SHUTDOWN, CSessionAddr(GetLocalInAddr(), 0), CSessionAddr(*pos, 0), bForward );
			CSockAddrIn dstaddr( *pos, NCP_SERVER_PING_PORT );
			SendMessageTo( sock, &msg, dstaddr );
		}
	}else{
		//send shutdown to a specific addresse
		CMessageBase msg;
		msg.Init( NCM_SHUTDOWN, CSessionAddr(GetLocalInAddr(), 0), CSessionAddr(addrHost, 0), bForward );
		CSockAddrIn dstaddr( addrHost, NCP_SERVER_PING_PORT );
		SendMessageTo( sock, &msg, dstaddr );
	}
}
Exemple #5
0
//poll all the registered hosts
void CClientManager::DoPoll( SOCKET sock, unsigned short sPort ){
	vector<IN_ADDR> arrAddrs;
	{
		CObjLocker<CClientManager> locker(this);
		arrAddrs.resize( m_HostAddrs.size() );
		copy( m_HostAddrs.begin(), m_HostAddrs.end(), arrAddrs.begin() );
	}
	SOCKADDR_IN dstaddr;
	dstaddr.sin_family = AF_INET;
	dstaddr.sin_port = htons( NCP_SERVER_PING_PORT );

	for( int i=0; i<arrAddrs.size(); i++ ){
		CMessageBase msg(NCM_POLLSERVER);
		msg.Init( NCM_POLLSERVER, CSessionAddr(), CSessionAddr(), sPort );
		dstaddr.sin_addr = arrAddrs[i];
		SendMessageTo( sock, &msg, dstaddr );
	}
}
Exemple #6
0
void Server::DisconnetClient(SOCKET socket, const std::string message)
{
	SendMessageTo(socket, message);
	closesocket(socket);
}
Exemple #7
0
	void CLANConnection::Run()
	{
		VERIFY(AfxSocketInit());

		// Socket erzeugen, falls noch nicht geschehen
		int nError;
		if (!CreateSocket(nError))
		{
			if (m_pListener)
			{
				m_pListener->OnSocketError(nError, this);
				m_pListener->OnConnectionLost(this);
			}
			return;
		}

		CAsyncSocket socket;
		ASSERT(m_hSocket != INVALID_SOCKET);
		socket.Attach(m_hSocket);

		// IP-Adresse und tatsächlichen Port ermitteln
		SOCKADDR_IN sockaddr;
		memset(&sockaddr, 0, sizeof(sockaddr));
		int nSockAddrLen = sizeof(SOCKADDR_IN);
		if (!socket.GetSockName((SOCKADDR *)&sockaddr, &nSockAddrLen)) goto error;

		m_nPort = ntohs(sockaddr.sin_port);
		m_dwIP = ntohl(sockaddr.sin_addr.S_un.S_addr);

		// main thread loop
		BYTE buf[LAN_BUFSIZE];
		while (!IsInterrupted())
		{
			// Senden
			{
			CReference<CLANMessage> message;
			if (message = GetNextMessage())
			{
				// Magic Number
				memcpy(buf, "BotE", 4);

				// Nachricht serialisieren
				CMemFile memFile(&buf[4], LAN_BUFSIZE - 4);
				CArchive ar(&memFile, CArchive::store);
				message->Serialize(ar);
				ar.Close();
				UINT nSize = memFile.GetPosition() + 4;
				memFile.Detach();

				// Empfänger setzen
				memset(&sockaddr, 0, sizeof(sockaddr));
				sockaddr.sin_family = AF_INET;
				sockaddr.sin_addr.S_un.S_addr = htonl(message->GetReceiverIP());
				sockaddr.sin_port = htons(message->GetReceiverPort());

				// Nachricht versenden, setzt bei Fehler m_bInterrupted
				if (!SendMessageTo(socket, message, buf, nSize, &sockaddr)) break;

				// Broadcast-Nachricht auch an den lokalen Host senden
				if (message->GetReceiverIP() == INADDR_BROADCAST)
				{
					sockaddr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
					if (!SendMessageTo(socket, message, buf, nSize, &sockaddr))
						break;
				}
			}
			}

			// Empfangen
			memset(&sockaddr, 0, sizeof(sockaddr));
			int nSockAddrLen = sizeof(sockaddr);
			int nCount = socket.ReceiveFrom(&buf, LAN_BUFSIZE, (SOCKADDR *)&sockaddr, &nSockAddrLen);
			if (nCount > 0)
			{
				// Magic Number prüfen
				if (memcmp(&buf, "BotE", 4) != 0) continue;

				// Nachricht deserialisieren
				CMemFile memFile(&buf[4], nCount - 4);
				CArchive ar(&memFile, CArchive::load);
				CReference<CLANMessage> message(new CLANMessage());
				message->Serialize(ar);
				ar.Close();
				memFile.Detach();

				// IP und Port des Absenders
				DWORD dwIP = ntohl(sockaddr.sin_addr.S_un.S_addr);
				UINT nPort = ntohs(sockaddr.sin_port);
				message->SetSenderIP(dwIP);
				message->SetSenderPort(nPort);

				// Ankunft einer Nachricht melden
				if (m_pListener) m_pListener->OnMessageReceived(message, this);
			}
			else if (nCount == 0)
			{
				// "Verbindung" wurde getrennt
				ASSERT(FALSE);
				break;
			}
			else if (nCount == SOCKET_ERROR)
			{
				int nError = socket.GetLastError();
				if (nError != WSAEWOULDBLOCK)
				{
					if (m_pListener) m_pListener->OnSocketError(nError, this);
					// WSAECONNRESET tritt auf, wenn wir zuvor eine Nachricht an eine Adresse gesendet
					// haben, an der kein Server läuft; Thread dann nicht abbrechen
					if (nError != WSAECONNRESET)
					{
						__super::Interrupt();
						break;
					}
				}
			}

			Sleep(50);
		}

		// verbleibende Nachrichten löschen
		{
			CReference<CLANMessage> message;
			while (message = GetNextMessage())
			{
				if (m_pListener) m_pListener->OnMessageDiscarded(message, this);
			}
		}

		// socket schließen, Thread beenden
		socket.Close();
		m_hSocket = INVALID_SOCKET;
		if (m_bSendLost && m_pListener) m_pListener->OnConnectionLost(this);
		return;

error:
		if (m_pListener) m_pListener->OnSocketError(socket.GetLastError(), this);
		m_hSocket = INVALID_SOCKET;
		if (m_pListener) m_pListener->OnConnectionLost(this);
	}