Files
SLikeNet/Samples/FlowControlTest/FlowControlTest.cpp
2025-11-24 14:19:51 +05:30

270 lines
7.2 KiB
C++

/*
* 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-2018, 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/statistics.h"
#include <cstdio>
#include <memory.h>
#include <cstring>
#include <stdlib.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;
int main(void)
{
RakPeerInterface *rakServer;
RakPeerInterface *rakClient;
int ch;
char str[255], remoteIP[255];
char randomData[8192];
unsigned short localPort, remotePort;
int packetSize;
int sendinterval;
SLNet::TimeMS time;
SLNet::Packet *p;
SLNet::TimeMS lastPacketReceipt, lastNotification, lastSend;
#ifndef _WIN32
char buff[256];
#endif
memset(randomData, 255, sizeof(randomData));
printf("This project is used to test two systems sending to each other with\n");
printf("variable message sends rates and payload sizes\n");
printf("Difficulty: Beginner\n\n");
printf("Start relay (s)erver or start (c)lient?\n");
#ifndef _WIN32
Gets(buff,sizeof(buff));
ch=buff[0];
#else
ch=_getch();
#endif
if (ch=='s' || ch=='S')
{
printf("Acting as server.\n");
rakServer= SLNet::RakPeerInterface::GetInstance();
rakClient=0;
}
else
{
printf("Acting as client.\n");
rakClient= SLNet::RakPeerInterface::GetInstance();
rakServer=0;
}
printf("Enter local port: ");
Gets(str, sizeof(str));
if (str[0]==0)
{
if (rakServer)
localPort=60000;
else
localPort=0;
}
else
{
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 2;
}
localPort = static_cast<unsigned short>(intLocalPort);
}
if (rakServer)
{
SLNet::SocketDescriptor socketDescriptor(localPort,0);
rakServer->Startup(100, &socketDescriptor, 1);
rakServer->SetMaximumIncomingConnections(100);
}
else
{
printf("Enter remote IP: ");
Gets(remoteIP,sizeof(remoteIP));
if (remoteIP[0]==0)
strcpy_s(remoteIP, "127.0.0.1");
printf("Enter remote port: ");
Gets(str, sizeof(str));
if (str[0]==0)
remotePort=60000;
else
{
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 3;
}
remotePort = static_cast<unsigned short>(intRemotePort);
}
SLNet::SocketDescriptor socketDescriptor(localPort,0);
rakClient->Startup(1, &socketDescriptor, 1);
rakClient->Connect(remoteIP, remotePort, 0, 0);
}
printf("Entering loop.\nHit 'h' for help.\nHit 'q' to quit\n'i' to increase send interval\n'd' to decrease send interval\n'+' to increase packet size\n'-' to decrease packet size.\nSpace to show current statistics\n");
sendinterval=128;
packetSize=64;
lastPacketReceipt=lastNotification= SLNet::GetTimeMS();
lastSend=0;
for(;;)
{
time= SLNet::GetTimeMS();
if (_kbhit())
{
#ifndef _WIN32
Gets(buff,sizeof(buff));
ch=buff[0];
#else
ch=_getch();
#endif
if (ch=='q')
{
printf("Quitting\n");
break;
}
else if (ch=='i')
{
sendinterval*=2;
printf("Send interval is now %i\n", sendinterval);
}
else if (ch=='d')
{
if (sendinterval>1)
sendinterval/=2;
printf("Send interval is now %i\n", sendinterval);
}
if (ch=='h')
printf("Hit 'h' for help.\nHit 'q' to quit\n'i' to increase send interval\n'd' to decrease send interval\n'+' to increase packet size\n'-' to decrease packet size.\nSpace to show current statistics\n");
else if (ch=='+')
{
if (packetSize < 8192)
packetSize*=2;
printf("Packet size is now %i\n", packetSize);
}
else if (ch=='-')
{
if (packetSize>1)
packetSize/=2;
printf("Packet size is now %i\n", packetSize);
}
else if (ch==' ')
{
if (rakServer)
{
StatisticsToString(rakServer->GetStatistics(rakServer->GetSystemAddressFromIndex(0)), randomData, 8192, 1);
printf("%s", randomData);
}
else
{
StatisticsToString(rakClient->GetStatistics(rakClient->GetSystemAddressFromIndex(0)), randomData, 8192, 1);
printf("%s", randomData);
}
printf("Send interval is %i\n", sendinterval);
printf("Packet size is %i\n", packetSize);
printf("\n");
}
ch=0;
}
// get packets
if (rakServer)
p = rakServer->Receive();
else
p=rakClient->Receive();
if (p)
{
lastPacketReceipt= SLNet::GetTimeMS();
switch (p->data[0])
{
case ID_CONNECTION_REQUEST_ACCEPTED:
printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
break;
case ID_DISCONNECTION_NOTIFICATION:
// Connection lost normally
printf("ID_DISCONNECTION_NOTIFICATION\n");
break;
case ID_NEW_INCOMING_CONNECTION:
// Somebody connected. We have their IP now
printf("ID_NEW_INCOMING_CONNECTION\n");
break;
case ID_CONNECTION_LOST:
// Couldn't deliver a reliable packet - i.e. the other system was abnormally
// terminated
printf("ID_CONNECTION_LOST\n");
break;
default:
// Relay
if (rakServer)
rakServer->Send((char*)p->data, p->length, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true);
}
if (rakServer)
rakServer->DeallocatePacket(p);
else
rakClient->DeallocatePacket(p);
}
if ((rakServer && rakServer->NumberOfConnections()>0) ||
(rakClient && rakClient->NumberOfConnections()>0))
{
// Do sends
if (lastSend + (SLNet::TimeMS)sendinterval < time)
{
if (rakServer)
{
rakServer->Send((char*)randomData, packetSize, HIGH_PRIORITY, RELIABLE_ORDERED, 0, SLNet::UNASSIGNED_SYSTEM_ADDRESS, true);
}
else if (rakClient)
{
rakClient->Send((char*)randomData, packetSize, HIGH_PRIORITY, RELIABLE_ORDERED, 0, SLNet::UNASSIGNED_SYSTEM_ADDRESS, true);
}
lastSend=time;
}
if (lastPacketReceipt + 500 < (unsigned int)time && lastNotification + 500 < (unsigned int)time)
{
lastNotification=time;
printf("Warning: No packets for %i ms. Possibly a spike.\n", time - lastPacketReceipt);
}
}
}
if (rakServer)
SLNet::RakPeerInterface::DestroyInstance(rakServer);
else
SLNet::RakPeerInterface::DestroyInstance(rakClient);
return 1;
}