Android RakNet Series 7-thread and server statistical test, androidraknet

Source: Internet
Author: User

Android RakNet Series 7-thread and server statistical test, androidraknet
Introduction

A thread is a single sequential control flow in a program. A relatively independent and schedulable execution unit in a process is the basic unit for Independent System Scheduling and CPU allocation, which refers to the scheduling unit of the running program. It is called multithreading.

The thread is re-encapsulated in Raknet, and the class is RakThread.

A good server is reflected in the maximum rate of memory usage, but not every programmer can grasp the memory. What should we check if there is a problem on the server? Logs.

Logs are the server's black box, which counts the server's information.

Raknet also provides server connection statistics.

Thread details class definition

class RAK_DLL_EXPORT RakThread{public:/// Create a thread, simplified to be cross platform without all the extra junk/// To then start that thread, call RakCreateThread(functionName, arguments);/// \param[in] start_address Function you want to call/// \param[in] arglist Arguments to pass to the function/// \return 0=success. >0 = error code/*nice value Win32 Priority-20 to -16 THREAD_PRIORITY_HIGHEST-15 to -6 THREAD_PRIORITY_ABOVE_NORMAL-5 to +4 THREAD_PRIORITY_NORMAL+5 to +14 THREAD_PRIORITY_BELOW_NORMAL+15 to +19 THREAD_PRIORITY_LOWEST*/#if defined(_WIN32_WCE)static int Create( LPTHREAD_START_ROUTINE start_address, void *arglist, int priority=0);#elif defined(_XBOX) || defined(X360)                                                                                              #elif defined(_WIN32)static int Create( unsigned __stdcall start_address( void* ), void *arglist, int priority=0);#elsestatic int Create( void* start_address( void* ), void *arglist, int priority=0);#endif};

Provides multiple platforms

#if defined(_XBOX) || defined(X360)                                                  #elif defined(_WIN32)#include "WindowsIncludes.h"#include <stdio.h>#if !defined(_WIN32_WCE)#include <process.h>#endif#else#include <pthread.h>#endif

Test

for (i=0; i< 10; i++){count[i]=i;RakNet::RakThread::Create(&ProducerThread, count+i);}for (; i < 20; i++){count[i]=i;RakNet::RakThread::Create(&ConsumerThread, count+i );}
RAK_THREAD_DECLARATION(ProducerThread){char i = *((char *) arguments);char out[2];out[0]=ID_USER_PACKET_ENUM;out[1]=i;while (endThreads==false){printf("Thread %i writing...\n", i);if (i&1)peer1->Send(out, 2, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);elsepeer2->Send(out, 2, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);printf("Thread %i done writing\n", i);RakSleep(500);}return 0;}RAK_THREAD_DECLARATION(ConsumerThread){char i = *((char *) arguments);RakNet::Packet *p;while (endThreads==false){printf("Thread %i reading...\n", i);if (i&1)p=peer1->Receive();elsep=peer2->Receive();printf("Thread %i done reading...\n", i);if (p){if (p->data[0]==ID_USER_PACKET_ENUM)printf("Got data from thread %i\n", p->data[1]);if (i&1)peer1->DeallocatePacket(p);elsepeer2->DeallocatePacket(p);}        RakSleep(500);}return 0;}

Effect



Statistical details

Class Definition

// Connects, sends data over time, disconnects, repeatclass Client{public:Client(){peer = RakNet::RakPeerInterface::GetInstance();}~Client(){RakNet::RakPeerInterface::DestroyInstance(peer);}void Startup(void){RakNet::SocketDescriptor socketDescriptor;

{peer->CloseConnection(peer->GetSystemAddressFromIndex(0),true,0);isConnected=false;}void Update(RakNet::TimeMS curTime){Packet *p = peer->Receive();while (p){switch (p->data[0]){case ID_CONNECTION_REQUEST_ACCEPTED:printf("ID_CONNECTION_REQUEST_ACCEPTED\n");isConnected=true;break;// print out errorscase ID_CONNECTION_ATTEMPT_FAILED:printf("Client Error: ID_CONNECTION_ATTEMPT_FAILED\n");isConnected=false;break;case ID_ALREADY_CONNECTED:printf("Client Error: ID_ALREADY_CONNECTED\n");break;case ID_CONNECTION_BANNED:printf("Client Error: ID_CONNECTION_BANNED\n");break;case ID_INVALID_PASSWORD:printf("Client Error: ID_INVALID_PASSWORD\n");break;case ID_INCOMPATIBLE_PROTOCOL_VERSION:printf("Client Error: ID_INCOMPATIBLE_PROTOCOL_VERSION\n");break;case ID_NO_FREE_INCOMING_CONNECTIONS:printf("Client Error: ID_NO_FREE_INCOMING_CONNECTIONS\n");isConnected=false;break;case ID_DISCONNECTION_NOTIFICATION://printf("ID_DISCONNECTION_NOTIFICATION\n");isConnected=false;break;case ID_CONNECTION_LOST:printf("Client Error: ID_CONNECTION_LOST\n");isConnected=false;break;}peer->DeallocatePacket(p);p = peer->Receive();}if (curTime>nextSendTime && isConnected){peer->Send((const char*)&randomData,RANDOM_DATA_SIZE,HIGH_PRIORITY,RELIABLE_ORDERED,0,RakNet::UNASSIGNED_SYSTEM_ADDRESS,true);nextSendTime=curTime+30;}}bool isConnected;RakPeerInterface *peer;RakNet::TimeMS nextSendTime;};

// Just listens for ID_USER_PACKET_ENUM and validates its integrityclass Server{public:Server(){peer = RakNet::RakPeerInterface::GetInstance();}~Server(){RakNet::RakPeerInterface::DestroyInstance(peer);}void Start(void){RakNet::SocketDescriptor socketDescriptor;socketDescriptor.port=(unsigned short) SERVER_PORT;bool b = peer->Startup((unsigned short) NUM_CLIENTS,&socketDescriptor,1)==RakNet::RAKNET_STARTED;RakAssert(b);peer->SetMaximumIncomingConnections(NUM_CLIENTS);}unsigned ConnectionCount(void) const{unsigned i,count;for (i=0,count=0; i < NUM_CLIENTS;i++)if (peer->GetSystemAddressFromIndex(i)!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)count++;return count;}void Update(RakNet::TimeMS curTime){Packet *p = peer->Receive();while (p){switch (p->data[0]){case ID_CONNECTION_LOST:case ID_DISCONNECTION_NOTIFICATION:case ID_NEW_INCOMING_CONNECTION:printf("Connections = %i\n", ConnectionCount());break;case ID_USER_PACKET_ENUM:{if (memcmp(p->data, randomData, RANDOM_DATA_SIZE)!=0){printf("Bad data on server!\n");}break;}}peer->DeallocatePacket(p);p = peer->Receive();}}RakPeerInterface *peer;};
Test

int main(void){Client clients[NUM_CLIENTS];Server server;//int clientIndex;int mode;printf("Connects many clients to a single server.\n");printf("Difficulty: Intermediate\n\n");printf("Run as (S)erver or (C)lient or (B)oth? ");char ch = getche();static char *remoteIP="94.198.81.195";static char *localIP="127.0.0.1";if (ch=='s' || ch=='S')mode=0;else if (ch=='c' || ch=='c'){mode=1;remoteIPAddress=remoteIP;}else{mode=2;remoteIPAddress=localIP;}printf("\n");unsigned i;randomData[0]=ID_USER_PACKET_ENUM;for (i=0; i < RANDOM_DATA_SIZE-1; i++)randomData[i+1]=i;if (mode==0 || mode==2){server.Start();printf("Started server\n");}if (mode==1 || mode==2){printf("Starting clients...\n");for (i=0; i < NUM_CLIENTS; i++)clients[i].Startup();printf("Started clients\n");printf("Connecting clients...\n");for (i=0; i < NUM_CLIENTS; i++)clients[i].Connect();printf("Done.\n");}RakNet::TimeMS endTime = RakNet::GetTimeMS()+60000*5;RakNet::TimeMS time = RakNet::GetTimeMS();while (time < endTime){if (mode==0 || mode==2)server.Update(time);if (mode==1 || mode==2){for (i=0; i < NUM_CLIENTS; i++)clients[i].Update(time);}if (kbhit()){char ch = getch();if (ch==' '){FILE *fp;char text[2048];if (mode==0 || mode==2){printf("Logging server statistics to ServerStats.txt\n");fp=fopen("ServerStats.txt","wt");for (i=0; i < NUM_CLIENTS; i++){RakNetStatistics *rssSender;rssSender=server.peer->GetStatistics(server.peer->GetSystemAddressFromIndex(i));StatisticsToString(rssSender, text, 3);fprintf(fp,"==== System %i ====\n", i+1);fprintf(fp,"%s\n\n", text);}fclose(fp);}if (mode==1 || mode==2){printf("Logging client statistics to ClientStats.txt\n");fp=fopen("ClientStats.txt","wt");for (i=0; i < NUM_CLIENTS; i++){RakNetStatistics *rssSender;rssSender=clients[i].peer->GetStatistics(clients[i].peer->GetSystemAddressFromIndex(0));StatisticsToString(rssSender, text, 3);fprintf(fp,"==== Client %i ====\n", i+1);fprintf(fp,"%s\n\n", text);}fclose(fp);}}if (ch=='q' || ch==0)break;}time = RakNet::GetTimeMS();RakSleep(30);}if (mode==0 || mode==2)server.peer->Shutdown(0);if (mode==1 || mode==2)for (i=0; i < NUM_CLIENTS; i++)clients[i].peer->Shutdown(0);printf("Test completed");return 0;}

Effect



Summary

This example tests Raknet threads and statistics, but to be familiar with threads, you also need to master the following knowledge:
Thread stack model and thread variables, thread state conversion, thread synchronization and lock, thread interaction, thread scheduling-sleep, thread scheduling-priority, thread scheduling-concession thread Scheduling-merge, thread scheduling-daemon thread, thread synchronization-synchronization method, thread synchronization-synchronization block, concurrent collaboration-producer consumer model, concurrent collaboration-deadlock, volatile keywords, thread pool, threads with returned values, locks, semaphores, blocking queues, blocking stacks, condition variables, atomic weights, barrier.
It's hard for you to master this knowledge.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.