void SendMessage(MessageConnection *connection) { NetworkMessage *msg = connection->StartNewMessage(191 /*A custom message number*/, 4 + extraBytes + 4 /*size of this message in bytes*/); msg->priority = 100; msg->reliable = true; msg->inOrder = true; msg->contentID = 1; DataSerializer ds(msg->data, msg->Size()); ++lastMessageNumber; ds.Add<u32>(lastMessageNumber); u32 checksum = 0; for(int i = 0; i < extraBytes; ++i) { u8 byte = (u8)rand(); ds.Add<u8>(byte); // Just run some bit-twiddling algorithm over all the bits to generate a checksum. checksum ^= byte; checksum <<= NumBitsSet(byte); } ds.Add<u32>(checksum); connection->EndAndQueueMessage(msg); }
void NetworkServer::BroadcastMessage(unsigned long id, bool reliable, bool inOrder, unsigned long priority, unsigned long contentID, const char *data, size_t numBytes, MessageConnection *exclude) { PolledTimer timer; Lockable<ConnectionMap>::LockType clientsLock = clients.Acquire(); if (timer.MSecsElapsed() >= 50.f) { LOG(LogWaits, "NetworkServer::BroadcastMessage: Accessing the connection list took %f msecs.", timer.MSecsElapsed()); } for(ConnectionMap::iterator iter = clientsLock->begin(); iter != clientsLock->end(); ++iter) { MessageConnection *connection = iter->second; assert(connection); if (connection == exclude || !connection->IsWriteOpen()) continue; NetworkMessage *msg = connection->StartNewMessage(id, numBytes); msg->reliable = reliable; msg->inOrder = inOrder; msg->priority = priority; msg->contentID = contentID; assert(msg->data); assert(msg->Size() == numBytes); memcpy(msg->data, data, numBytes); connection->EndAndQueueMessage(msg); } }
void SendPingReplyMessage(MessageConnection *connection, const char *receivedPingData, size_t receivedPingDataNumBytes) { DataDeserializer dd(receivedPingData, receivedPingDataNumBytes); NetworkMessage *msg = connection->StartNewMessage(customPingReplyMessageId, 2); msg->priority = 100; msg->reliable = false; DataSerializer ds(msg->data, msg->Size()); u16 pingNumber = dd.Read<u16>(); ds.Add<u16>(pingNumber); connection->EndAndQueueMessage(msg); cout << "Received PING_" << pingNumber << ". Sent PONG_" << pingNumber << "." << endl; }
void SendPingMessage(MessageConnection *connection) { NetworkMessage *msg = connection->StartNewMessage(customPingMessageId, 2); msg->priority = 100; msg->reliable = false; DataSerializer ds(msg->data, msg->Size()); ++sentPingNumber; ds.Add<u16>(sentPingNumber); connection->EndAndQueueMessage(msg); pingSendTime = Clock::Tick(); cout << "Sent PING_" << sentPingNumber << "." << endl; }
void MessageConnection::SendMessage(unsigned long id, bool reliable, bool inOrder, unsigned long priority, unsigned long contentID, const char *data, size_t numBytes) { AssertInMainThreadContext(); NetworkMessage *msg = StartNewMessage(id, numBytes); if (!msg) { LOG(LogError, "MessageConnection::SendMessage: StartNewMessage failed! Discarding message send."); return; } msg->reliable = reliable; msg->inOrder = inOrder; msg->priority = priority; msg->contentID = contentID; assert(msg->data); assert(msg->Size() == numBytes); memcpy(msg->data, data, numBytes); EndAndQueueMessage(msg); }
void NetworkApp::SenderMainLoopIteration() { if (connection->IsWriteOpen()) { connection->Process(); // Add new data fragments into the queue. const int outboundMsgQueueSize = 1000; int i = outboundMsgQueueSize - connection->NumOutboundMessagesPending(); while(i-- > 0 && connection->IsWriteOpen() && bytesSent < fileSize) { // File payload data bytes in this message. const size_t bytesInThisFragment = min((int)fragmentSize, fileSize - bytesSent); NetworkMessage *msg = connection->StartNewMessage(cFileTransferFragment, bytesInThisFragment+4); msg->priority = 100; msg->reliable = true; msg->inOrder = true; #ifdef KNET_NETWORK_PROFILING msg->profilerName = "File (31)"; #endif DataSerializer ds(msg->data, msg->Size()); ds.Add<u32>(nextFragment++); #ifndef NULLTRANSFER size_t read = fread(ds.GetData() + ds.BytesFilled(), sizeof(char), bytesInThisFragment, handle); #else size_t read = bytesInThisFragment; #endif if (read < bytesInThisFragment) { LOG(LogUser, "Failed to read file!"); connection->Close(0); } connection->EndAndQueueMessage(msg); bytesSent += bytesInThisFragment; } // If we've put out all file fragments to the network, close the connection down. if (connection->IsWriteOpen() && bytesSent >= fileSize && connection->NumOutboundMessagesPending() == 0) { LOG(LogUser, "All data sent. Disconnecting."); connection->Disconnect(15000); } if (statsPrintTimer.Test()) { const tick_t sendFinishTick = Clock::Tick(); double timespan = (float)Clock::TimespanToSecondsD(transferStartTick, sendFinishTick); LOG(LogUser, "Sending fragment %d. Elapsed: %.2f seconds. Bytes sent: %d. Transfer rate: %s/sec.", nextFragment-1, (float)timespan, bytesSent, FormatBytes((bytesSent/timespan)).c_str()); connection->DumpStatus(); statsPrintTimer.StartMSecs((float)printIntervalMSecs); } } if (!connection->IsReadOpen() && (connection->NumOutboundMessagesPending() == 0 || !connection->IsWriteOpen())) { connection->Close(15000); fclose(handle); QApplication::quit(); } else QTimer::singleShot(10, this, SLOT(SenderMainLoopIteration())); }