Init
This commit is contained in:
385
Samples/ReliableOrderedTest/ReliableOrderedTest.cpp
Normal file
385
Samples/ReliableOrderedTest/ReliableOrderedTest.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Original work: Copyright (c) 2014, Oculus VR, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
|
||||
*
|
||||
*
|
||||
* Modified work: Copyright (c) 2016-2019, SLikeSoft UG (haftungsbeschränkt)
|
||||
*
|
||||
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
|
||||
* license found in the license.txt file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "slikenet/peerinterface.h"
|
||||
#include "slikenet/GetTime.h"
|
||||
#include "slikenet/MessageIdentifiers.h"
|
||||
#include "slikenet/BitStream.h"
|
||||
#include <cstdio>
|
||||
#include <memory.h>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include "slikenet/Rand.h"
|
||||
#include "slikenet/statistics.h"
|
||||
#include "slikenet/sleep.h"
|
||||
#include "slikenet/memoryoverride.h"
|
||||
#include <stdio.h>
|
||||
#include <limits> // used for std::numeric_limits
|
||||
#include "slikenet/Gets.h"
|
||||
#include "slikenet/Kbhit.h"
|
||||
#include "slikenet/linux_adapter.h"
|
||||
#include "slikenet/osx_adapter.h"
|
||||
|
||||
using namespace SLNet;
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "slikenet/WindowsIncludes.h" // Sleep
|
||||
#else
|
||||
#include <unistd.h> // usleep
|
||||
#endif
|
||||
|
||||
FILE *fp;
|
||||
int memoryUsage=0;
|
||||
void *LoggedMalloc(size_t size, const char *file, unsigned int line)
|
||||
{
|
||||
memoryUsage+=size;
|
||||
if (fp)
|
||||
fprintf(fp,"Alloc %s:%i %i bytes %i total\n", file,line,size,memoryUsage);
|
||||
char *p = (char*) malloc(size+sizeof(size));
|
||||
memcpy(p,&size,sizeof(size));
|
||||
return p+sizeof(size);
|
||||
}
|
||||
void LoggedFree(void *p, const char *file, unsigned int line)
|
||||
{
|
||||
char *realP=(char*)p-sizeof(size_t);
|
||||
size_t allocatedSize;
|
||||
memcpy(&allocatedSize,realP,sizeof(size_t));
|
||||
memoryUsage-=allocatedSize;
|
||||
if (fp)
|
||||
fprintf(fp,"Free %s:%i %i bytes %i total\n", file,line,allocatedSize,memoryUsage);
|
||||
free(realP);
|
||||
}
|
||||
void* LoggedRealloc(void *p, size_t size, const char *file, unsigned int line)
|
||||
{
|
||||
char *realP=(char*)p-sizeof(size_t);
|
||||
size_t allocatedSize;
|
||||
memcpy(&allocatedSize,realP,sizeof(size_t));
|
||||
memoryUsage-=allocatedSize;
|
||||
memoryUsage+=size;
|
||||
p = realloc(realP,size+sizeof(size));
|
||||
memcpy(p,&size,sizeof(size));
|
||||
if (fp)
|
||||
fprintf(fp,"Realloc %s:%i %i to %i bytes %i total\n", file,line,allocatedSize,size,memoryUsage);
|
||||
return (char*)p+sizeof(size);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RakPeerInterface *sender, *receiver;
|
||||
unsigned int packetNumber[32], receivedPacketNumber;
|
||||
SLNet::Time receivedTime;
|
||||
char str[256];
|
||||
char ip[32];
|
||||
// initialize to silence false-positive warning C4701 with VS2015+
|
||||
SLNet::Time sendInterval = 0;
|
||||
SLNet::Time nextSend, currentTime, quitTime;
|
||||
unsigned short remotePort, localPort;
|
||||
unsigned char streamNumber;
|
||||
SLNet::BitStream bitStream;
|
||||
SLNet::Packet *packet;
|
||||
bool doSend=false;
|
||||
|
||||
for (int i=0; i < 32; i++)
|
||||
packetNumber[i]=0;
|
||||
|
||||
printf("This project tests RakNet's reliable ordered sending system.\n");
|
||||
printf("Difficulty: Beginner\n\n");
|
||||
|
||||
printf("Act as (s)ender or (r)eceiver?\n");
|
||||
Gets(str, sizeof(str));
|
||||
if (str[0]==0)
|
||||
return 1;
|
||||
|
||||
if (argc==2)
|
||||
{
|
||||
fopen_s(&fp,argv[1],"wt");
|
||||
SetMalloc_Ex(LoggedMalloc);
|
||||
SetRealloc_Ex(LoggedRealloc);
|
||||
SetFree_Ex(LoggedFree);
|
||||
}
|
||||
else
|
||||
fp=0;
|
||||
|
||||
if (str[0]=='s' || str[0]=='S')
|
||||
{
|
||||
sender = SLNet::RakPeerInterface::GetInstance();
|
||||
|
||||
receiver = 0;
|
||||
|
||||
printf("Enter number of ms to pass between sends: ");
|
||||
Gets(str, sizeof(str));
|
||||
if (str[0]==0)
|
||||
sendInterval=33;
|
||||
else
|
||||
sendInterval=atoi(str);
|
||||
|
||||
printf("Enter remote IP: ");
|
||||
Gets(ip, sizeof(ip));
|
||||
if (ip[0]==0)
|
||||
strcpy_s(ip, "127.0.0.1");
|
||||
// strcpy_s(ip, "natpunch.slikesoft.com");
|
||||
|
||||
printf("Enter remote port: ");
|
||||
Gets(str, sizeof(str));
|
||||
if (str[0]==0)
|
||||
strcpy_s(str, "60000");
|
||||
const int intRemotePort = atoi(str);
|
||||
if ((intRemotePort < 0) || (intRemotePort > std::numeric_limits<unsigned short>::max())) {
|
||||
printf("Specified remote port %d is outside valid bounds [0, %u]", intRemotePort, std::numeric_limits<unsigned short>::max());
|
||||
return 2;
|
||||
}
|
||||
remotePort = static_cast<unsigned short>(intRemotePort);
|
||||
|
||||
printf("Enter local port: ");
|
||||
Gets(str, sizeof(str));
|
||||
if (str[0]==0)
|
||||
strcpy_s(str, "0");
|
||||
const int intLocalPort = atoi(str);
|
||||
if ((intLocalPort < 0) || (intLocalPort > std::numeric_limits<unsigned short>::max())) {
|
||||
printf("Specified local port %d is outside valid bounds [0, %u]", intLocalPort, std::numeric_limits<unsigned short>::max());
|
||||
return 3;
|
||||
}
|
||||
localPort = static_cast<unsigned short>(intLocalPort);
|
||||
|
||||
|
||||
printf("Connecting...\n");
|
||||
SLNet::SocketDescriptor socketDescriptor(localPort,0);
|
||||
sender->Startup(8, &socketDescriptor, 1);
|
||||
// sender->ApplyNetworkSimulator(.2, 0, 0);
|
||||
sender->Connect(ip, remotePort, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
receiver = SLNet::RakPeerInterface::GetInstance();
|
||||
// receiver->ApplyNetworkSimulator(.2, 0, 0);
|
||||
sender=0;
|
||||
|
||||
printf("Enter local port: ");
|
||||
Gets(str, sizeof(str));
|
||||
if (str[0]==0)
|
||||
strcpy_s(str, "60000");
|
||||
const int intLocalPort = atoi(str);
|
||||
if ((intLocalPort < 0) || (intLocalPort > std::numeric_limits<unsigned short>::max())) {
|
||||
printf("Specified local port %d is outside valid bounds [0, %u]", intLocalPort, std::numeric_limits<unsigned short>::max());
|
||||
return 3;
|
||||
}
|
||||
localPort = static_cast<unsigned short>(intLocalPort);
|
||||
|
||||
printf("Waiting for connections...\n");
|
||||
SLNet::SocketDescriptor socketDescriptor(localPort,0);
|
||||
receiver->Startup(8, &socketDescriptor, 1);
|
||||
receiver->SetMaximumIncomingConnections(8);
|
||||
}
|
||||
|
||||
seedMT(1);
|
||||
|
||||
printf("How long to run this test for, in seconds?\n");
|
||||
Gets(str, sizeof(str));
|
||||
if (str[0]==0)
|
||||
strcpy_s(str, "12000");
|
||||
|
||||
currentTime = SLNet::GetTimeMS();
|
||||
quitTime = atoi(str) * 1000 + currentTime;
|
||||
|
||||
nextSend=currentTime;
|
||||
|
||||
printf("Test running.\n");
|
||||
|
||||
//while (currentTime < quitTime)
|
||||
for(;;)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_kbhit())
|
||||
{
|
||||
int ch=_getch();
|
||||
if (ch=='q')
|
||||
break;
|
||||
else if (ch==' ')
|
||||
{
|
||||
RakNetStatistics *rss;
|
||||
char message[2048];
|
||||
if (sender)
|
||||
rss=sender->GetStatistics(sender->GetSystemAddressFromIndex(0));
|
||||
else
|
||||
rss=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0));
|
||||
StatisticsToString(rss, message, 2048, 2);
|
||||
printf("%s", message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (sender)
|
||||
{
|
||||
uint32_t msgNumber;
|
||||
packet = sender->Receive();
|
||||
while (packet)
|
||||
{
|
||||
// PARSE TYPES
|
||||
switch(packet->data[0])
|
||||
{
|
||||
case ID_CONNECTION_REQUEST_ACCEPTED:
|
||||
printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
|
||||
doSend=true;
|
||||
nextSend=currentTime;
|
||||
break;
|
||||
case ID_NO_FREE_INCOMING_CONNECTIONS:
|
||||
printf("ID_NO_FREE_INCOMING_CONNECTIONS\n");
|
||||
break;
|
||||
case ID_DISCONNECTION_NOTIFICATION:
|
||||
printf("ID_DISCONNECTION_NOTIFICATION\n");
|
||||
break;
|
||||
case ID_CONNECTION_LOST:
|
||||
printf("ID_CONNECTION_LOST\n");
|
||||
break;
|
||||
case ID_CONNECTION_ATTEMPT_FAILED:
|
||||
printf("Connection attempt failed\n");
|
||||
break;
|
||||
case ID_SND_RECEIPT_ACKED:
|
||||
memcpy(&msgNumber, packet->data+1, 4);
|
||||
printf("Msg #%i was delivered.\n", msgNumber);
|
||||
break;
|
||||
case ID_SND_RECEIPT_LOSS:
|
||||
memcpy(&msgNumber, packet->data+1, 4);
|
||||
printf("Msg #%i was probably not delivered.\n", msgNumber);
|
||||
break;
|
||||
}
|
||||
|
||||
sender->DeallocatePacket(packet);
|
||||
packet = sender->Receive();
|
||||
}
|
||||
|
||||
char *type="UNDEFINED";
|
||||
while (doSend && currentTime > nextSend)
|
||||
{
|
||||
streamNumber=0;
|
||||
streamNumber = randomMT() % 4;
|
||||
// Do the send
|
||||
|
||||
for (int i=0; i < 2; i++)
|
||||
{
|
||||
bitStream.Reset();
|
||||
bitStream.Write((unsigned char) (ID_TIMESTAMP));
|
||||
bitStream.Write(SLNet::GetTime());
|
||||
bitStream.Write((unsigned char) (ID_USER_PACKET_ENUM+1));
|
||||
bitStream.Write(packetNumber[streamNumber]);
|
||||
packetNumber[streamNumber]++;
|
||||
bitStream.Write(streamNumber);
|
||||
|
||||
PacketReliability reliability;
|
||||
// #med - review --- was commented out in RakNet via if(0)
|
||||
/*if (0 && (randomMT()%2)==0)
|
||||
{
|
||||
type="UNRELIABLE_SEQUENCED";
|
||||
reliability=UNRELIABLE_SEQUENCED;
|
||||
}
|
||||
else
|
||||
{*/
|
||||
type="RELIABLE_ORDERED";
|
||||
reliability=RELIABLE_ORDERED;
|
||||
//}
|
||||
|
||||
int padLength;
|
||||
padLength = (randomMT() % 25000) + 1;
|
||||
bitStream.Write(reliability);
|
||||
bitStream.PadWithZeroToByteLength(padLength);
|
||||
|
||||
if (sender->Send(&bitStream, HIGH_PRIORITY, reliability ,streamNumber, SLNet::UNASSIGNED_SYSTEM_ADDRESS, true)==0)
|
||||
{
|
||||
packetNumber[streamNumber]--;
|
||||
}
|
||||
}
|
||||
|
||||
// RakNetStatistics *rssSender;
|
||||
//rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0));
|
||||
|
||||
printf("Snd: %i, %s, time %" PRINTF_64_BIT_MODIFIER "u, length %i\n", packetNumber[streamNumber]-1, type, currentTime, bitStream.GetNumberOfBytesUsed());
|
||||
|
||||
nextSend+=sendInterval;
|
||||
|
||||
// Test halting
|
||||
// if (rand()%20==0)
|
||||
// nextSend+=1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet = receiver->Receive();
|
||||
while (packet)
|
||||
{
|
||||
switch(packet->data[0])
|
||||
{
|
||||
case ID_NEW_INCOMING_CONNECTION:
|
||||
printf("ID_NEW_INCOMING_CONNECTION\n");
|
||||
break;
|
||||
case ID_DISCONNECTION_NOTIFICATION:
|
||||
printf("ID_DISCONNECTION_NOTIFICATION\n");
|
||||
break;
|
||||
case ID_CONNECTION_LOST:
|
||||
printf("ID_CONNECTION_LOST\n");
|
||||
break;
|
||||
case ID_TIMESTAMP:
|
||||
bitStream.Reset();
|
||||
bitStream.Write((char*)packet->data, packet->length);
|
||||
bitStream.IgnoreBits(8); // Ignore ID_TIMESTAMP
|
||||
bitStream.Read(receivedTime);
|
||||
bitStream.IgnoreBits(8); // Ignore ID_USER_ENUM+1
|
||||
bitStream.Read(receivedPacketNumber);
|
||||
bitStream.Read(streamNumber);
|
||||
PacketReliability reliability;
|
||||
bitStream.Read(reliability);
|
||||
char *type="UNDEFINED";
|
||||
if (reliability==UNRELIABLE_SEQUENCED)
|
||||
type="UNRELIABLE_SEQUENCED";
|
||||
else if (reliability==RELIABLE_ORDERED)
|
||||
type="RELIABLE_ORDERED";
|
||||
|
||||
if (receivedPacketNumber>packetNumber[streamNumber])
|
||||
printf("Skipped %i got %i %s (channel %i).\n",packetNumber[streamNumber], receivedPacketNumber, type, streamNumber);
|
||||
else if (receivedPacketNumber<packetNumber[streamNumber])
|
||||
printf("Out of order packet! Expecting %i got %i %s (channel %i).\n",packetNumber[streamNumber], receivedPacketNumber, type, streamNumber);
|
||||
else
|
||||
printf("Got %i.%s.CH:%i.Len:%i.\n", packetNumber[streamNumber], type, streamNumber, packet->length);
|
||||
|
||||
// printf("Sent=%" PRINTF_64_BIT_MODIFIER "u Received=%" PRINTF_64_BIT_MODIFIER "u Diff=%i.\n", receivedTime, currentTime, (int)(currentTime - receivedTime));
|
||||
|
||||
packetNumber[streamNumber]=receivedPacketNumber+1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
receiver->DeallocatePacket(packet);
|
||||
packet = receiver->Receive();
|
||||
}
|
||||
}
|
||||
|
||||
// DO NOT COMMENT OUT THIS SLEEP!
|
||||
// This sleep keeps RakNet responsive
|
||||
#ifdef _WIN32
|
||||
Sleep(0);
|
||||
#else
|
||||
usleep(0);
|
||||
#endif
|
||||
currentTime= SLNet::GetTimeMS();
|
||||
}
|
||||
|
||||
if (sender)
|
||||
SLNet::RakPeerInterface::DestroyInstance(sender);
|
||||
if (receiver)
|
||||
SLNet::RakPeerInterface::DestroyInstance(receiver);
|
||||
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user