1 #include "RakPeerInterface.h"
2 #include "RakNetworkFactory.h"
3 #include "BitStream.h"
4 #include <stdlib.h> // For atoi
5 #include <cstring> // For strlen
6 #include "Rand.h"
7 #include "RakNetStatistics.h"
8 #include "MessageIdentifiers.h"
9 #include <stdio.h>
10 #include "Kbhit.h"
11 #include "GetTime.h"
12 #include "RakAssert.h"
13 #include "RakSleep.h"
14
15
16 #ifdef _WIN32
17 #include "WindowsIncludes.h" // Sleep
18 #else
19 #include <unistd.h> // usleep
20 #include <cstdio>
21 #include "Getche.h"
22 #endif
23
24 static const int NUM_CLIENTS=128;
25 #define SERVER_PORT 66666
26 #define RANDOM_DATA_SIZE 32
27 char randomData[RANDOM_DATA_SIZE];
28 char *remoteIPAddress=0;
29
30 // Connects, sends data over time, disconnects, repeat
31 class Client
32 {
33 public:
Client()34 Client()
35 {
36 peer = RakNetworkFactory::GetRakPeerInterface();
37 }
~Client()38 ~Client()
39 {
40 RakNetworkFactory::DestroyRakPeerInterface(peer);
41 }
Startup(void)42 void Startup(void)
43 {
44 SocketDescriptor socketDescriptor;
45 socketDescriptor.port=0;
46 nextSendTime=0;
47 bool b = peer->Startup(1,30,&socketDescriptor,1);
48 RakAssert(b);
49 isConnected=false;
50 }
Connect(void)51 void Connect(void)
52 {
53 bool b;
54 b=peer->Connect(remoteIPAddress, (unsigned short) SERVER_PORT, 0, 0, 0);
55 if (b==false)
56 {
57 printf("Client connect call failed!\n");
58 }
59 }
Disconnect(void)60 void Disconnect(void)
61 {
62 peer->CloseConnection(peer->GetSystemAddressFromIndex(0),true,0);
63 isConnected=false;
64 }
Update(RakNetTime curTime)65 void Update(RakNetTime curTime)
66 {
67 Packet *p = peer->Receive();
68 while (p)
69 {
70 switch (p->data[0])
71 {
72 case ID_CONNECTION_REQUEST_ACCEPTED:
73 printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
74 isConnected=true;
75 break;
76 // print out errors
77 case ID_CONNECTION_ATTEMPT_FAILED:
78 printf("Client Error: ID_CONNECTION_ATTEMPT_FAILED\n");
79 isConnected=false;
80 break;
81 case ID_ALREADY_CONNECTED:
82 printf("Client Error: ID_ALREADY_CONNECTED\n");
83 break;
84 case ID_CONNECTION_BANNED:
85 printf("Client Error: ID_CONNECTION_BANNED\n");
86 break;
87 case ID_INVALID_PASSWORD:
88 printf("Client Error: ID_INVALID_PASSWORD\n");
89 break;
90 case ID_INCOMPATIBLE_PROTOCOL_VERSION:
91 printf("Client Error: ID_INCOMPATIBLE_PROTOCOL_VERSION\n");
92 break;
93 case ID_NO_FREE_INCOMING_CONNECTIONS:
94 printf("Client Error: ID_NO_FREE_INCOMING_CONNECTIONS\n");
95 isConnected=false;
96 break;
97 case ID_DISCONNECTION_NOTIFICATION:
98 //printf("ID_DISCONNECTION_NOTIFICATION\n");
99 isConnected=false;
100 break;
101 case ID_CONNECTION_LOST:
102 printf("Client Error: ID_CONNECTION_LOST\n");
103 isConnected=false;
104 break;
105 case ID_MODIFIED_PACKET:
106 printf("Client Error: ID_MODIFIED_PACKET\n");
107 break;
108 }
109 peer->DeallocatePacket(p);
110 p = peer->Receive();
111
112 }
113
114 if (curTime>nextSendTime && isConnected)
115 {
116 peer->Send((const char*)&randomData,RANDOM_DATA_SIZE,HIGH_PRIORITY,RELIABLE_ORDERED,0,UNASSIGNED_SYSTEM_ADDRESS,true);
117 nextSendTime=curTime+30;
118 }
119 }
120
121 bool isConnected;
122 RakPeerInterface *peer;
123 RakNetTime nextSendTime;
124 };
125
126 // Just listens for ID_USER_PACKET_ENUM and validates its integrity
127 class Server
128 {
129 public:
Server()130 Server()
131 {
132 peer = RakNetworkFactory::GetRakPeerInterface();
133 }
~Server()134 ~Server()
135 {
136 RakNetworkFactory::DestroyRakPeerInterface(peer);
137 }
Start(void)138 void Start(void)
139 {
140 SocketDescriptor socketDescriptor;
141 socketDescriptor.port=(unsigned short) SERVER_PORT;
142 bool b = peer->Startup((unsigned short) NUM_CLIENTS,0,&socketDescriptor,1);
143 RakAssert(b);
144 peer->SetMaximumIncomingConnections(NUM_CLIENTS);
145 }
ConnectionCount(void) const146 unsigned ConnectionCount(void) const
147 {
148 unsigned i,count;
149 for (i=0,count=0; i < NUM_CLIENTS;i++)
150 if (peer->GetSystemAddressFromIndex(i)!=UNASSIGNED_SYSTEM_ADDRESS)
151 count++;
152 return count;
153 }
Update(RakNetTime curTime)154 void Update(RakNetTime curTime)
155 {
156 Packet *p = peer->Receive();
157 while (p)
158 {
159 switch (p->data[0])
160 {
161 case ID_CONNECTION_LOST:
162 case ID_DISCONNECTION_NOTIFICATION:
163 case ID_NEW_INCOMING_CONNECTION:
164 printf("Connections = %i\n", ConnectionCount());
165 break;
166 case ID_USER_PACKET_ENUM:
167 {
168 if (memcmp(p->data, randomData, RANDOM_DATA_SIZE)!=0)
169 {
170 printf("Bad data on server!\n");
171 }
172 break;
173 }
174 }
175 peer->DeallocatePacket(p);
176 p = peer->Receive();
177 }
178 }
179
180
181 RakPeerInterface *peer;
182 };
183
main(void)184 int main(void)
185 {
186 Client clients[NUM_CLIENTS];
187 Server server;
188 // int clientIndex;
189 int mode;
190
191 printf("Connects many clients to a single server.\n");
192 printf("Difficulty: Intermediate\n\n");
193 printf("Run as (S)erver or (C)lient or (B)oth? ");
194 char ch = getche();
195 static char *remoteIP="94.198.81.195";
196 static char *localIP="127.0.0.1";
197 if (ch=='s' || ch=='S')
198 mode=0;
199 else if (ch=='c' || ch=='c')
200 {
201 mode=1;
202 remoteIPAddress=remoteIP;
203 }
204 else
205 {
206 mode=2;
207 remoteIPAddress=localIP;
208 }
209 printf("\n");
210
211 unsigned i;
212 randomData[0]=ID_USER_PACKET_ENUM;
213 for (i=0; i < RANDOM_DATA_SIZE-1; i++)
214 randomData[i+1]=i;
215
216 if (mode==0 || mode==2)
217 {
218 server.Start();
219 printf("Started server\n");
220 }
221 if (mode==1 || mode==2)
222 {
223 printf("Starting clients...\n");
224 for (i=0; i < NUM_CLIENTS; i++)
225 clients[i].Startup();
226 printf("Started clients\n");
227 printf("Connecting clients...\n");
228 for (i=0; i < NUM_CLIENTS; i++)
229 clients[i].Connect();
230 printf("Done.\n");
231 }
232
233 RakNetTime endTime = RakNet::GetTime()+60000*5;
234 RakNetTime time = RakNet::GetTime();
235 while (time < endTime)
236 {
237 if (mode==0 || mode==2)
238 server.Update(time);
239 if (mode==1 || mode==2)
240 {
241 for (i=0; i < NUM_CLIENTS; i++)
242 clients[i].Update(time);
243 }
244
245 if (kbhit())
246 {
247 char ch = getch();
248 if (ch==' ')
249 {
250 FILE *fp;
251 char text[2048];
252 if (mode==0 || mode==2)
253 {
254 printf("Logging server statistics to ServerStats.txt\n");
255 fp=fopen("ServerStats.txt","wt");
256 for (i=0; i < NUM_CLIENTS; i++)
257 {
258 RakNetStatistics *rssSender;
259 rssSender=server.peer->GetStatistics(server.peer->GetSystemAddressFromIndex(i));
260 StatisticsToString(rssSender, text, 3);
261 fprintf(fp,"==== System %i ====\n", i+1);
262 fprintf(fp,"%s\n\n", text);
263 }
264 fclose(fp);
265 }
266 if (mode==1 || mode==2)
267 {
268 printf("Logging client statistics to ClientStats.txt\n");
269 fp=fopen("ClientStats.txt","wt");
270 for (i=0; i < NUM_CLIENTS; i++)
271 {
272 RakNetStatistics *rssSender;
273 rssSender=clients[i].peer->GetStatistics(clients[i].peer->GetSystemAddressFromIndex(0));
274 StatisticsToString(rssSender, text, 3);
275 fprintf(fp,"==== Client %i ====\n", i+1);
276 fprintf(fp,"%s\n\n", text);
277 }
278 fclose(fp);
279 }
280 }
281 if (ch=='q' || ch==0)
282 break;
283 }
284
285 time = RakNet::GetTime();
286 RakSleep(30);
287 }
288
289 if (mode==0 || mode==2)
290 server.peer->Shutdown(0);
291 if (mode==1 || mode==2)
292 for (i=0; i < NUM_CLIENTS; i++)
293 clients[i].peer->Shutdown(0);
294
295 printf("Test completed");
296 return 0;
297 }
298