mirror of
https://github.com/ValveSoftware/GameNetworkingSockets.git
synced 2026-05-29 16:20:34 +00:00
Update unit test.
This commit is contained in:
+354
-178
@@ -1,5 +1,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
@@ -13,10 +15,51 @@
|
||||
|
||||
#define PORT_SERVER 27200 // Default server port, UDP/TCP
|
||||
|
||||
static void DebugOutput( int /*eType*/, const char *pszMsg )
|
||||
static std::default_random_engine g_rand;
|
||||
static SteamNetworkingMicroseconds g_usecTestElapsed;
|
||||
|
||||
FILE *g_fpLog = nullptr;
|
||||
SteamNetworkingMicroseconds g_logTimeZero;
|
||||
|
||||
static void DebugOutput( int eType, const char *pszMsg )
|
||||
{
|
||||
printf( "%s\n", pszMsg );
|
||||
fflush(stdout);
|
||||
SteamNetworkingMicroseconds time = SteamNetworkingUtils()->GetLocalTimestamp() - g_logTimeZero;
|
||||
if ( g_fpLog )
|
||||
fprintf( g_fpLog, "%10.6f %s\n", time*1e-6, pszMsg );
|
||||
if ( eType <= k_ESteamNetworkingSocketsDebugOutputType_Msg )
|
||||
{
|
||||
printf( "%10.6f %s\n", time*1e-6, pszMsg );
|
||||
fflush(stdout);
|
||||
}
|
||||
if ( eType == k_ESteamNetworkingSocketsDebugOutputType_Bug )
|
||||
{
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
if ( g_fpLog )
|
||||
fflush( g_fpLog );
|
||||
|
||||
// !KLUDGE! Our logging (which is done while we hold the lock)
|
||||
// is occasionally triggering this assert. Just ignroe that one
|
||||
// error for now.
|
||||
// Yes, this is a kludge.
|
||||
if ( strstr( pszMsg, "SteamDatagramTransportLock held for" ) )
|
||||
return;
|
||||
|
||||
assert( !"TEST FAILED" );
|
||||
}
|
||||
}
|
||||
|
||||
static void Printf( const char *fmt, ... )
|
||||
{
|
||||
char text[ 2048 ];
|
||||
va_list ap;
|
||||
va_start( ap, fmt );
|
||||
vsprintf( text, fmt, ap );
|
||||
va_end(ap);
|
||||
char *nl = strchr( text, '\0' ) - 1;
|
||||
if ( nl >= text && *nl == '\n' )
|
||||
*nl = '\0';
|
||||
DebugOutput( k_ESteamNetworkingSocketsDebugOutputType_Msg, text );
|
||||
}
|
||||
|
||||
static void InitSteamDatagramConnectionSockets()
|
||||
@@ -39,7 +82,12 @@ static void InitSteamDatagramConnectionSockets()
|
||||
}
|
||||
#endif
|
||||
|
||||
SteamNetworkingSockets_SetDebugOutputFunction( k_ESteamNetworkingSocketsDebugOutputType_Verbose, DebugOutput );
|
||||
g_fpLog = fopen( "log.txt", "wt" );
|
||||
g_logTimeZero = SteamNetworkingUtils()->GetLocalTimestamp();
|
||||
|
||||
SteamNetworkingSockets_SetDebugOutputFunction( k_ESteamNetworkingSocketsDebugOutputType_Debug, DebugOutput );
|
||||
//SteamNetworkingSockets_SetDebugOutputFunction( k_ESteamNetworkingSocketsDebugOutputType_Verbose, DebugOutput );
|
||||
//SteamNetworkingSockets_SetDebugOutputFunction( k_ESteamNetworkingSocketsDebugOutputType_Msg, DebugOutput );
|
||||
}
|
||||
|
||||
static void ShutdownSteamDatagramConnectionSockets()
|
||||
@@ -56,15 +104,16 @@ static HSteamListenSocket g_hSteamListenSocket = k_HSteamListenSocket_Invalid;
|
||||
struct TestMsg
|
||||
{
|
||||
int64 m_nMsgNum;
|
||||
SteamNetworkingMicroseconds m_usecWhenSent;
|
||||
bool m_bReliable;
|
||||
int m_cbSize;
|
||||
static constexpr int k_cbMaxSize = 20*1000;
|
||||
static constexpr int k_cbMaxSize = 10*1000;
|
||||
uint8 m_data[ k_cbMaxSize ];
|
||||
};
|
||||
|
||||
struct SSteamNetConnection
|
||||
struct SFakePeer
|
||||
{
|
||||
SSteamNetConnection( const char *pName )
|
||||
SFakePeer( const char *pName )
|
||||
: m_sName( pName )
|
||||
{
|
||||
}
|
||||
@@ -74,106 +123,122 @@ struct SSteamNetConnection
|
||||
int64 m_nSendMsgCount = 0;
|
||||
int64 m_nReliableExpectedRecvMsg = 1;
|
||||
int64 m_nExpectedRecvMsg = 1;
|
||||
float m_flReliableMsgDelay = 0.0f;
|
||||
float m_flUnreliableMsgDelay = 0.0f;
|
||||
HSteamNetConnection m_hSteamNetConnection = k_HSteamNetConnection_Invalid;
|
||||
SteamNetworkingMicroseconds m_usecLastTransmit = 0;
|
||||
SteamNetworkingMicroseconds m_usecTransmitTime = 0;
|
||||
bool m_bIsConnected = false;
|
||||
int m_nMaxPendingBytes = 384 * 1024;
|
||||
bool m_bQuiet = true;
|
||||
SteamNetworkingMicroseconds m_usecQuietDuration = 5000000;
|
||||
SteamNetworkingMicroseconds m_usecActiveDuration = 10000000;
|
||||
SteamNetworkingMicroseconds m_usecWhenStateEnd = 0;
|
||||
SteamNetworkingQuickConnectionStatus m_info;
|
||||
float m_flSendReliableRate = 0.0f;
|
||||
float m_flRecvReliableRate = 0.0f;
|
||||
int64 m_nSendReliableInterval = 0;
|
||||
int64 m_nRecvReliableInterval = 0;
|
||||
|
||||
inline void UpdateInterval( float flElapsed )
|
||||
{
|
||||
m_flSendReliableRate = m_nSendReliableInterval / flElapsed;
|
||||
m_flRecvReliableRate = m_nRecvReliableInterval / flElapsed;
|
||||
|
||||
m_nSendReliableInterval = 0;
|
||||
m_nRecvReliableInterval = 0;
|
||||
}
|
||||
|
||||
inline void UpdateStats()
|
||||
{
|
||||
SteamNetworkingSockets()->GetQuickConnectionStatus( m_hSteamNetConnection, &m_info );
|
||||
}
|
||||
|
||||
inline int GetQueuedSendBytes()
|
||||
{
|
||||
return m_info.m_cbPendingReliable + m_info.m_cbPendingUnreliable;
|
||||
}
|
||||
|
||||
inline void PrintStatus()
|
||||
{
|
||||
Printf( "%-10s: %8d pending %4d ping %5.1f%% qual\n",
|
||||
m_sName.c_str(), m_info.m_cbPendingReliable + m_info.m_cbPendingUnreliable,
|
||||
m_info.m_nPing, m_info.m_flConnectionQualityLocal*100.0f );
|
||||
Printf( "%-10s reliable %5.1fKB out %5.1fKB in msg: %6lld out %6lld in %4.0fms delay\n",
|
||||
"", m_flSendReliableRate, m_flRecvReliableRate,
|
||||
(long long)m_nReliableSendMsgCount, (long long)m_nReliableExpectedRecvMsg,
|
||||
m_flReliableMsgDelay*1000.0f
|
||||
);
|
||||
}
|
||||
|
||||
void SendRandomMessage( bool bReliable, int cbMaxSize )
|
||||
{
|
||||
TestMsg msg;
|
||||
msg.m_bReliable = bReliable;
|
||||
msg.m_usecWhenSent = SteamNetworkingUtils()->GetLocalTimestamp();
|
||||
msg.m_cbSize = std::uniform_int_distribution<>( 20, cbMaxSize )( g_rand );
|
||||
//bIsReliable = false;
|
||||
//nBytes = 1200-13;
|
||||
|
||||
msg.m_nMsgNum = msg.m_bReliable ? ++m_nReliableSendMsgCount : ++m_nSendMsgCount;
|
||||
for ( int n = 0; n < msg.m_cbSize; ++n )
|
||||
{
|
||||
msg.m_data[n] = (uint8)( msg.m_nMsgNum + n );
|
||||
}
|
||||
|
||||
int cbSend = (int)( sizeof(msg) - sizeof(msg.m_data) + msg.m_cbSize );
|
||||
if ( bReliable )
|
||||
{
|
||||
m_nSendReliableInterval += cbSend;
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_nRecvReliableInterval += pIncomingMsg->GetSize();
|
||||
}
|
||||
|
||||
EResult result = SteamNetworkingSockets()->SendMessageToConnection(
|
||||
m_hSteamNetConnection,
|
||||
&msg,
|
||||
cbSend,
|
||||
msg.m_bReliable ? k_ESteamNetworkingSendType_Reliable : k_ESteamNetworkingSendType_Unreliable );
|
||||
|
||||
if ( result != k_EResultOK )
|
||||
{
|
||||
Printf( "***ERROR ON Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n",
|
||||
m_sName.c_str(),
|
||||
g_usecTestElapsed*1e-6,
|
||||
msg.m_bReliable ? "reliable" : "unreliable",
|
||||
(long long)msg.m_nMsgNum,
|
||||
msg.m_cbSize,
|
||||
GetQueuedSendBytes() );
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
Printf( "Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n",
|
||||
connection.m_sName.c_str(),
|
||||
g_usecTestElapsed*1e-6,
|
||||
msg.m_bReliable ? "reliable" : "unreliable",
|
||||
(long long)msg.m_nMsgNum,
|
||||
msg.m_cbSize,
|
||||
GetQueuedSendBytes() );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Send()
|
||||
{
|
||||
bool bReliable = std::uniform_real_distribution<>()( g_rand ) < .60;
|
||||
SendRandomMessage( bReliable, bReliable ? TestMsg::k_cbMaxSize : 2000 );
|
||||
}
|
||||
};
|
||||
|
||||
static SSteamNetConnection g_connectionServer( "Server" );
|
||||
static SSteamNetConnection g_connectionClient( "Client" );
|
||||
|
||||
static std::default_random_engine g_rand;
|
||||
static SteamNetworkingMicroseconds g_usecTestElapsed;
|
||||
|
||||
static void Send( ISteamNetworkingSockets *pSteamSocketNetworking, SSteamNetConnection &connection )
|
||||
{
|
||||
if ( connection.m_hSteamNetConnection == k_HSteamNetConnection_Invalid )
|
||||
return;
|
||||
|
||||
if ( g_usecTestElapsed - connection.m_usecLastTransmit < connection.m_usecTransmitTime )
|
||||
return;
|
||||
|
||||
// Start and stop active use of the connection. This exercizes a bunch of important edge cases
|
||||
// such as keepalives, the bandwidth estimation, etc.
|
||||
if ( g_usecTestElapsed > connection.m_usecWhenStateEnd )
|
||||
{
|
||||
connection.m_bQuiet = !connection.m_bQuiet;
|
||||
connection.m_usecWhenStateEnd = g_usecTestElapsed +
|
||||
( connection.m_bQuiet ? connection.m_usecQuietDuration : connection.m_usecActiveDuration );
|
||||
}
|
||||
if ( connection.m_bQuiet )
|
||||
return;
|
||||
|
||||
TestMsg msg;
|
||||
msg.m_bReliable = std::uniform_real_distribution<>()( g_rand ) < .75;
|
||||
msg.m_cbSize = std::uniform_int_distribution<>( 20, msg.m_bReliable ? TestMsg::k_cbMaxSize : 5000 )( g_rand );
|
||||
//bIsReliable = false;
|
||||
//nBytes = 1200-13;
|
||||
|
||||
// Don't send unless we are clear
|
||||
SteamNetworkingQuickConnectionStatus info;
|
||||
pSteamSocketNetworking->GetQuickConnectionStatus( connection.m_hSteamNetConnection, &info );
|
||||
|
||||
if ( info.m_cbPendingReliable + info.m_cbPendingUnreliable >= connection.m_nMaxPendingBytes )
|
||||
{
|
||||
// Log_Msg( LOG_NETWORKING_STEAMCONNECTIONS, "Send: %s stopped due to %d bytes pending\n",
|
||||
// connection.m_sName.c_str(), connection.m_nMaxPendingBytes );
|
||||
return; // Still stuff in the buffer
|
||||
}
|
||||
|
||||
connection.m_usecLastTransmit = g_usecTestElapsed;
|
||||
|
||||
msg.m_nMsgNum = msg.m_bReliable ? ++connection.m_nReliableSendMsgCount : ++connection.m_nSendMsgCount;
|
||||
for ( int n = 0; n < msg.m_cbSize; ++n )
|
||||
{
|
||||
msg.m_data[n] = (uint8)( msg.m_nMsgNum + n );
|
||||
}
|
||||
|
||||
EResult result = pSteamSocketNetworking->SendMessageToConnection(
|
||||
connection.m_hSteamNetConnection,
|
||||
&msg,
|
||||
(uint32)( sizeof(msg) - sizeof(msg.m_data) + msg.m_cbSize ),
|
||||
msg.m_bReliable ? k_ESteamNetworkingSendType_Reliable : k_ESteamNetworkingSendType_Unreliable );
|
||||
|
||||
if ( result != k_EResultOK )
|
||||
{
|
||||
fprintf( stderr, "***ERROR ON Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n",
|
||||
connection.m_sName.c_str(),
|
||||
g_usecTestElapsed*1e-6,
|
||||
msg.m_bReliable ? "reliable" : "unreliable",
|
||||
(long long)msg.m_nMsgNum,
|
||||
msg.m_cbSize,
|
||||
info.m_cbPendingReliable + info.m_cbPendingUnreliable );
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
printf( "Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n",
|
||||
connection.m_sName.c_str(),
|
||||
g_usecTestElapsed*1e-6,
|
||||
msg.m_bReliable ? "reliable" : "unreliable",
|
||||
(long long)msg.m_nMsgNum,
|
||||
msg.m_cbSize,
|
||||
info.m_cbPendingReliable + info.m_cbPendingUnreliable );
|
||||
#endif
|
||||
}
|
||||
static SFakePeer g_peerServer( "Server" );
|
||||
static SFakePeer g_peerClient( "Client" );
|
||||
|
||||
static void Recv( ISteamNetworkingSockets *pSteamSocketNetworking )
|
||||
{
|
||||
|
||||
while ( true )
|
||||
{
|
||||
SSteamNetConnection *pConnection = &g_connectionServer;
|
||||
SFakePeer *pConnection = &g_peerServer;
|
||||
ISteamNetworkingMessage *pIncomingMsg = nullptr;
|
||||
int numMsgs = pSteamSocketNetworking->ReceiveMessagesOnConnection( pConnection->m_hSteamNetConnection, &pIncomingMsg, 1 );
|
||||
if ( numMsgs <= 0 )
|
||||
{
|
||||
pConnection = &g_connectionClient;
|
||||
pConnection = &g_peerClient;
|
||||
numMsgs = pSteamSocketNetworking->ReceiveMessagesOnConnection( pConnection->m_hSteamNetConnection, &pIncomingMsg, 1 );
|
||||
if ( numMsgs <= 0 )
|
||||
return;
|
||||
@@ -190,7 +255,7 @@ static void Recv( ISteamNetworkingSockets *pSteamSocketNetworking )
|
||||
{
|
||||
|
||||
// Print that it happened.
|
||||
printf(
|
||||
Printf(
|
||||
"Recv: %s, %s MISMATCH NUM wanted %lld got %lld\n",
|
||||
pConnection->m_sName.c_str(),
|
||||
pTestMsg->m_bReliable ? "RELIABLE" : "UNRELIABLE",
|
||||
@@ -201,6 +266,18 @@ static void Recv( ISteamNetworkingSockets *pSteamSocketNetworking )
|
||||
assert( !pTestMsg->m_bReliable );
|
||||
}
|
||||
|
||||
float flDelay = ( SteamNetworkingUtils()->GetLocalTimestamp() - pTestMsg->m_usecWhenSent ) * 1e-6f;
|
||||
if ( pTestMsg->m_bReliable )
|
||||
{
|
||||
pConnection->m_nRecvReliableInterval += pIncomingMsg->GetSize();
|
||||
pConnection->m_flReliableMsgDelay += ( flDelay - pConnection->m_flReliableMsgDelay ) * .25f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pConnection->m_flUnreliableMsgDelay += ( flDelay - pConnection->m_flUnreliableMsgDelay ) * .25f;
|
||||
//pConnection->m_nRecvUnreliableInterval += pIncomingMsg->GetSize();
|
||||
}
|
||||
|
||||
nExpectedMsgNum = pTestMsg->m_nMsgNum + 1;
|
||||
pIncomingMsg->Release();
|
||||
}
|
||||
@@ -216,7 +293,7 @@ struct TestSteamNetworkingSocketsCallbacks : public ISteamNetworkingSocketsCallb
|
||||
{
|
||||
case k_ESteamNetworkingConnectionState_ClosedByPeer:
|
||||
case k_ESteamNetworkingConnectionState_ProblemDetectedLocally:
|
||||
printf( "Steam Net connection %x %s, reason %d: %s\n",
|
||||
Printf( "Steam Net connection %x %s, reason %d: %s\n",
|
||||
pInfo->m_hConn,
|
||||
( pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer ? "closed by peer" : "problem detected locally" ),
|
||||
pInfo->m_info.m_eEndReason,
|
||||
@@ -226,20 +303,20 @@ struct TestSteamNetworkingSocketsCallbacks : public ISteamNetworkingSocketsCallb
|
||||
// Close our end
|
||||
SteamNetworkingSockets()->CloseConnection( pInfo->m_hConn, 0, nullptr, false );
|
||||
|
||||
if ( g_connectionServer.m_hSteamNetConnection == pInfo->m_hConn )
|
||||
if ( g_peerServer.m_hSteamNetConnection == pInfo->m_hConn )
|
||||
{
|
||||
g_connectionServer.m_hSteamNetConnection = k_HSteamNetConnection_Invalid;
|
||||
g_peerServer.m_hSteamNetConnection = k_HSteamNetConnection_Invalid;
|
||||
}
|
||||
if ( g_connectionClient.m_hSteamNetConnection == pInfo->m_hConn )
|
||||
if ( g_peerClient.m_hSteamNetConnection == pInfo->m_hConn )
|
||||
{
|
||||
g_connectionClient.m_hSteamNetConnection = k_HSteamNetConnection_Invalid;
|
||||
g_peerClient.m_hSteamNetConnection = k_HSteamNetConnection_Invalid;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
case k_ESteamNetworkingConnectionState_None:
|
||||
printf( "No steam Net connection %x (%s)\n", pInfo->m_hConn, pInfo->m_info.m_steamIDRemote.Render() );
|
||||
Printf( "No steam Net connection %x (%s)\n", pInfo->m_hConn, pInfo->m_info.m_steamIDRemote.Render() );
|
||||
|
||||
if ( g_hSteamNetConnection == pInfo->m_hConn )
|
||||
{
|
||||
@@ -255,21 +332,21 @@ struct TestSteamNetworkingSocketsCallbacks : public ISteamNetworkingSocketsCallb
|
||||
if ( g_hSteamListenSocket != k_HSteamListenSocket_Invalid && pInfo->m_info.m_hListenSocket == g_hSteamListenSocket )
|
||||
{
|
||||
// Somebody's knocking
|
||||
printf( "Accepting Steam Net connection %x\n", pInfo->m_hConn );
|
||||
g_connectionServer.m_hSteamNetConnection = pInfo->m_hConn;
|
||||
g_connectionServer.m_bIsConnected = true;
|
||||
Printf( "Accepting Steam Net connection %x\n", pInfo->m_hConn );
|
||||
g_peerServer.m_hSteamNetConnection = pInfo->m_hConn;
|
||||
g_peerServer.m_bIsConnected = true;
|
||||
SteamNetworkingSockets()->AcceptConnection( pInfo->m_hConn );
|
||||
SteamNetworkingSockets()->SetConnectionName( g_connectionServer.m_hSteamNetConnection, "Server" );
|
||||
SteamNetworkingSockets()->SetConnectionName( g_peerServer.m_hSteamNetConnection, "Server" );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case k_ESteamNetworkingConnectionState_Connected:
|
||||
if ( pInfo->m_hConn == g_connectionClient.m_hSteamNetConnection )
|
||||
if ( pInfo->m_hConn == g_peerClient.m_hSteamNetConnection )
|
||||
{
|
||||
g_connectionClient.m_bIsConnected = true;
|
||||
g_peerClient.m_bIsConnected = true;
|
||||
}
|
||||
printf( "Connected Steam Net connection %x\n", pInfo->m_hConn );
|
||||
Printf( "Connected Steam Net connection %x\n", pInfo->m_hConn );
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -279,67 +356,60 @@ struct TestSteamNetworkingSocketsCallbacks : public ISteamNetworkingSocketsCallb
|
||||
|
||||
static TestSteamNetworkingSocketsCallbacks g_Callbacks;
|
||||
|
||||
static void RunSteamDatagramConnectionTest()
|
||||
static void PumpCallbacks()
|
||||
{
|
||||
#ifndef STEAMNETWORKINGSOCKETS_OPENSOURCE
|
||||
SteamAPI_RunCallbacks();
|
||||
#endif
|
||||
SteamNetworkingSockets()->RunCallbacks( &g_Callbacks );
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 2 ) );
|
||||
}
|
||||
|
||||
static void PumpCallbacksAndMakeSureStillConnected()
|
||||
{
|
||||
PumpCallbacks();
|
||||
assert( g_peerClient.m_bIsConnected );
|
||||
assert( g_peerServer.m_bIsConnected );
|
||||
assert( g_peerServer.m_hSteamNetConnection != k_HSteamNetConnection_Invalid );
|
||||
assert( g_peerClient.m_hSteamNetConnection != k_HSteamNetConnection_Invalid );
|
||||
}
|
||||
|
||||
static void TestNetworkConditions( int rate, int loss, int lag, int reorderPct, int reorderLag, bool bActLikeGame )
|
||||
{
|
||||
ISteamNetworkingSockets *pSteamSocketNetworking = SteamNetworkingSockets();
|
||||
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_DebugWindow, 1 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_RTT, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Packet, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Segments, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Feedback, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Reliable, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Message, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Loss, 1 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_X, 0 );
|
||||
Printf( "---------------------------------------------------\n" );
|
||||
Printf( "NETWORK CONDITIONS\n" );
|
||||
Printf( "Rate . . . . . . : %d Bps\n", rate );
|
||||
Printf( "Loss . . . . . . : %d%%\n", loss );
|
||||
Printf( "Ping . . . . . . : %d\n", lag*2 );
|
||||
Printf( "Reorder. . . . . : %d%% @ %dms\n", reorderPct, reorderLag );
|
||||
Printf( "Act like game. . : %d\n", (int)bActLikeGame );
|
||||
Printf( "---------------------------------------------------\n" );
|
||||
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_MinRate, 1000000 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_MaxRate, 1000000 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_MinRate, rate );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_MaxRate, rate );
|
||||
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLoss_Send, 10 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLoss_Send, loss );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLoss_Recv, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLag_Send, 20 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketReorder_Send, 10 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketReorder_Time, 5 );
|
||||
// pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLag_Recv, 0 );
|
||||
|
||||
// Command line options:
|
||||
// -connect:ip -- don't create a server, just try to connect to the given ip
|
||||
// -serveronly -- don't create a client only create a server and wait for connection
|
||||
bool bServerOnly = false;//( CommandLine()->FindParm( "-serveronly" ) != 0 );
|
||||
bool bClientOnly = false;
|
||||
uint32 nConnectIP = 0x7f000001; // 127.0.0.1
|
||||
|
||||
//const char *s_pszConnectParm = "-connect:";
|
||||
//for ( int i = 0; i < CommandLine()->ParmCount(); ++i )
|
||||
//{
|
||||
// if ( V_strnicmp( CommandLine()->GetParm( i ), s_pszConnectParm, V_strlen( s_pszConnectParm ) ) == 0 )
|
||||
// {
|
||||
// bClientOnly = true;
|
||||
// connection_adr.SetFromString( CommandLine()->GetParm( i ) + V_strlen( s_pszConnectParm ) );
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
// Create listen socket
|
||||
if ( !bClientOnly )
|
||||
{
|
||||
g_hSteamListenSocket = pSteamSocketNetworking->CreateListenSocket( -1, 0x0u, PORT_SERVER );
|
||||
}
|
||||
if ( !bServerOnly )
|
||||
{
|
||||
g_connectionClient.m_hSteamNetConnection = pSteamSocketNetworking->ConnectByIPv4Address( nConnectIP, PORT_SERVER );
|
||||
pSteamSocketNetworking->SetConnectionName( g_connectionClient.m_hSteamNetConnection, "Client" );
|
||||
}
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLag_Send, lag );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketLag_Recv, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketReorder_Send, reorderPct );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_FakePacketReorder_Time, reorderLag );
|
||||
|
||||
SteamNetworkingMicroseconds usecWhenStarted = SteamNetworkingUtils()->GetLocalTimestamp();
|
||||
SteamNetworkingMicroseconds usecTestDuration = 120*1000000;
|
||||
SteamNetworkingMicroseconds usecWorstCase = usecTestDuration + 30*1000000;
|
||||
|
||||
// Loop!
|
||||
|
||||
//SteamNetworkingMicroseconds usecLastNow = usecWhenStarted;
|
||||
|
||||
SteamNetworkingMicroseconds usecQuietDuration = 5000000;
|
||||
SteamNetworkingMicroseconds usecActiveDuration = 10000000;
|
||||
bool bQuiet = true;
|
||||
SteamNetworkingMicroseconds usecWhenStateEnd = 0;
|
||||
int nIterations = 5;
|
||||
SteamNetworkingMicroseconds usecLastPrint = SteamNetworkingUtils()->GetLocalTimestamp();
|
||||
|
||||
while ( true )
|
||||
{
|
||||
SteamNetworkingMicroseconds now = SteamNetworkingUtils()->GetLocalTimestamp();
|
||||
@@ -352,41 +422,147 @@ static void RunSteamDatagramConnectionTest()
|
||||
//}
|
||||
//usecLastNow = now;
|
||||
|
||||
// Execute Steam net connection callbacks now
|
||||
#ifndef STEAMNETWORKINGSOCKETS_OPENSOURCE
|
||||
SteamAPI_RunCallbacks();
|
||||
#endif
|
||||
pSteamSocketNetworking->RunCallbacks( &g_Callbacks );
|
||||
g_peerServer.UpdateStats();
|
||||
g_peerClient.UpdateStats();
|
||||
|
||||
// Break out if we lose connection
|
||||
if ( !bServerOnly && g_connectionClient.m_hSteamNetConnection == k_HSteamNetConnection_Invalid )
|
||||
int nServerPending = g_peerServer.GetQueuedSendBytes();
|
||||
int nClientPending = g_peerClient.GetQueuedSendBytes();
|
||||
|
||||
// Start and stop active use of the connection. This exercizes a bunch of important edge cases
|
||||
// such as keepalives, the bandwidth estimation, etc.
|
||||
if ( g_usecTestElapsed > usecWhenStateEnd )
|
||||
{
|
||||
break;
|
||||
if ( bQuiet )
|
||||
{
|
||||
if ( nServerPending == 0 && nClientPending == 0 )
|
||||
{
|
||||
bQuiet = false;
|
||||
usecWhenStateEnd = g_usecTestElapsed + ( bQuiet ? usecQuietDuration : usecActiveDuration );
|
||||
if ( nIterations-- <= 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bQuiet = true;
|
||||
usecWhenStateEnd = g_usecTestElapsed + ( bQuiet ? usecQuietDuration : usecActiveDuration );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !g_connectionClient.m_bIsConnected && !g_connectionServer.m_bIsConnected )
|
||||
float flElapsedPrint = ( now - usecLastPrint ) * 1e-6f;
|
||||
if ( flElapsedPrint > 1.0f )
|
||||
{
|
||||
continue; // Just spin until connected
|
||||
g_peerServer.UpdateInterval( flElapsedPrint );
|
||||
g_peerClient.UpdateInterval( flElapsedPrint );
|
||||
g_peerServer.PrintStatus();
|
||||
g_peerClient.PrintStatus();
|
||||
usecLastPrint = now;
|
||||
}
|
||||
|
||||
Send( pSteamSocketNetworking, g_connectionServer );
|
||||
Send( pSteamSocketNetworking, g_connectionClient );
|
||||
|
||||
if ( !bQuiet )
|
||||
{
|
||||
if ( nServerPending < g_peerServer.m_nMaxPendingBytes )
|
||||
{
|
||||
if ( bActLikeGame )
|
||||
{
|
||||
g_peerServer.SendRandomMessage( true, 4000 );
|
||||
g_peerServer.SendRandomMessage( false, 2000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_peerServer.Send();
|
||||
}
|
||||
}
|
||||
if ( nClientPending < g_peerClient.m_nMaxPendingBytes )
|
||||
{
|
||||
if ( bActLikeGame )
|
||||
{
|
||||
g_peerClient.SendRandomMessage( true, 4000 );
|
||||
g_peerClient.SendRandomMessage( false, 2000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_peerClient.Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
PumpCallbacksAndMakeSureStillConnected();
|
||||
Recv( pSteamSocketNetworking );
|
||||
|
||||
if ( g_usecTestElapsed > usecTestDuration && g_connectionServer.m_hSteamNetConnection != k_HSteamNetConnection_Invalid )
|
||||
{
|
||||
pSteamSocketNetworking->CloseConnection( g_connectionServer.m_hSteamNetConnection, 0, nullptr, false );
|
||||
g_connectionServer.m_hSteamNetConnection = k_HSteamNetConnection_Invalid;
|
||||
}
|
||||
|
||||
// Make sure we haven't taken too long
|
||||
assert( g_usecTestElapsed < usecWorstCase );
|
||||
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||
if ( bActLikeGame )
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 30 ) );
|
||||
}
|
||||
}
|
||||
|
||||
static void RunSteamDatagramConnectionTest()
|
||||
{
|
||||
ISteamNetworkingSockets *pSteamSocketNetworking = SteamNetworkingSockets();
|
||||
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_DebugWindow, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_RTT, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Packet, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Segments, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Feedback, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Reliable, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Message, 0 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_Loss, 1 );
|
||||
pSteamSocketNetworking->SetConfigurationValue( k_ESteamNetworkingConfigurationValue_SNP_Log_X, 0 );
|
||||
|
||||
|
||||
// Command line options:
|
||||
// -connect:ip -- don't create a server, just try to connect to the given ip
|
||||
// -serveronly -- don't create a client only create a server and wait for connection
|
||||
uint32 nConnectIP = 0x7f000001; // 127.0.0.1
|
||||
|
||||
//const char *s_pszConnectParm = "-connect:";
|
||||
//for ( int i = 0; i < CommandLine()->ParmCount(); ++i )
|
||||
//{
|
||||
// if ( V_strnicmp( CommandLine()->GetParm( i ), s_pszConnectParm, V_strlen( s_pszConnectParm ) ) == 0 )
|
||||
// {
|
||||
// bClientOnly = true;
|
||||
// connection_adr.SetFromString( CommandLine()->GetParm( i ) + V_strlen( s_pszConnectParm ) );
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
// Initiate connection
|
||||
g_hSteamListenSocket = pSteamSocketNetworking->CreateListenSocket( -1, 0x0u, PORT_SERVER );
|
||||
g_peerClient.m_hSteamNetConnection = pSteamSocketNetworking->ConnectByIPv4Address( nConnectIP, PORT_SERVER );
|
||||
pSteamSocketNetworking->SetConnectionName( g_peerClient.m_hSteamNetConnection, "Client" );
|
||||
|
||||
// // Send a few random message, before we get connected, just to test that case
|
||||
// g_peerClient.SendRandomMessage( true );
|
||||
// g_peerClient.SendRandomMessage( true );
|
||||
// g_peerClient.SendRandomMessage( true );
|
||||
|
||||
// Wait for connection to complete
|
||||
while ( !g_peerClient.m_bIsConnected || !g_peerServer.m_bIsConnected )
|
||||
PumpCallbacks();
|
||||
|
||||
auto Test = []( int rate, int loss, int lag, int reorderPct, int reorderLag )
|
||||
{
|
||||
TestNetworkConditions( rate, loss, lag, reorderPct, reorderLag, true );
|
||||
TestNetworkConditions( rate, loss, lag, reorderPct, reorderLag, false );
|
||||
};
|
||||
|
||||
Test( 64000, 0, 0, 0, 0 );
|
||||
Test( 128000, 0, 0, 0, 0 );
|
||||
Test( 256000, 0, 0, 0, 0 );
|
||||
Test( 500000, 0, 0, 0, 0 );
|
||||
Test( 1000000, 0, 0, 0, 0 );
|
||||
Test( 2000000, 0, 0, 0, 0 );
|
||||
|
||||
Test( 64000, 1, 25, 1, 10 );
|
||||
Test( 1000000, 1, 25, 1, 10 );
|
||||
|
||||
Test( 64000, 5, 50, 2, 50 );
|
||||
Test( 1000000, 5, 50, 2, 10 );
|
||||
|
||||
Test( 64000, 20, 100, 4, 50 );
|
||||
Test( 128000, 20, 100, 4, 40 );
|
||||
Test( 500000, 20, 100, 4, 30 );
|
||||
Test( 1000000, 20, 100, 4, 10 );
|
||||
}
|
||||
|
||||
int main( )
|
||||
{
|
||||
// Create client and server sockets
|
||||
|
||||
Reference in New Issue
Block a user