Brief introduction
A thread is a single sequential control flow in a program. A relatively independent, scheduled execution unit within a process is the unit of dispatch for the system to dispatch and dispatch CPUs independently of the operating program. Running multiple threads at the same time in a single program accomplishes different tasks, called multithreading.
The thread is repackaged in the Raknet class: Rakthread.
A good service end is now the maximum rate of memory use, but not every programmer can grasp the memory, once the server has a problem, what do we look for? Log.
Log is the service side of the black box, statistics on the service side of the information.
The raknet also provides server-side connectivity statistics.
Thread Detail class definition
Class Rak_dll_export rakthread{public:///Create a thread, simplified to is cross platform without all the extra junk///T o then start this 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};
Multiple platforms are available
#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<; i++) {count[i]=i; Raknet::rakthread::create (&producerthread, count+i);} for (; i <; 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);p rintf ("Thread%i done writing\n", i); Raksleep (500);} return 0;} Rak_thread_declaration (consumerthread) {Char i = * ((char *) arguments); Raknet::P acket *p;while (endthreads==false) {printf ("Thread%i reading...\n", i); if (i&1) p=peer1->receive (); Elsep=peer2->receive ();p rintf ("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
Statistics details
Class definition
Connects, sends data over time, disconnects, Repeatclass client{public:client () {peer = Raknet::rakpeerinterface:: GetInstance ();} ~client () {raknet::rakpeerinterface::D estroyinstance (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::rakpeerint Erface::getinstance ();} ~server () {raknet::rakpeerinterface::D estroyinstance (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);p eer->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");p rintf ("Difficulty: intermediate\n\n ");p rintf (" 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 ();p rintf ("Started server\n");} if (mode==1 | | mode==2) {printf ("starting clients...\n"); for (i=0; i < num_clients; i++) clients[i]. Startup ();p rintf ("Started clients\n");p rintf ("Connecting clients...\n"); for (i=0; i < num_clients; i++) clients[i]. Connect ();p rintf ("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 Statis Tics 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"); (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].pe Er->shutdown (0);p rintf ("Test completed"); return 0;}
Effect
Summarize
This example tests raknet threads and statistics, but mastering threads requires the following knowledge:
Line stacks model and thread variables, thread state transitions, thread synchronization and locking, thread interaction, thread scheduling-hibernation, 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 models, concurrent collaboration-deadlocks, volatile keywords, thread pools, threads with return values, locks, semaphores, blocking queues, blocking stacks, condition variables, atomic weights, barriers.
Mastering this knowledge, you are not a very difficult.
Android raknet series of seven threads and service-side statistics test