// --------------------- // 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 } }
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; }
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 ); } }
//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 ); } }
void Server::DisconnetClient(SOCKET socket, const std::string message) { SendMessageTo(socket, message); closesocket(socket); }
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); }