DirectoryDeltaTransferTest.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "GetTime.h"
  11. #include "RakPeerInterface.h"
  12. #include "MessageIdentifiers.h"
  13. #include "RakNetStatistics.h"
  14. #include "DirectoryDeltaTransfer.h"
  15. #include "FileListTransfer.h"
  16. #include <cstdio>
  17. #include <stdlib.h>
  18. #include "Kbhit.h"
  19. #include "FileList.h"
  20. #include "DataCompressor.h"
  21. #include "FileListTransferCBInterface.h"
  22. #include "RakSleep.h"
  23. #include "IncrementalReadInterface.h"
  24. #include "PacketizedTCP.h"
  25. #include "Gets.h"
  26. #ifdef _WIN32
  27. #include "WindowsIncludes.h" // Sleep
  28. #else
  29. #include <unistd.h> // usleep
  30. #endif
  31. #define USE_TCP
  32. class TestCB : public RakNet::FileListTransferCBInterface
  33. {
  34. public:
  35. bool OnFile(
  36. OnFileStruct *onFileStruct)
  37. {
  38. assert(onFileStruct->byteLengthOfThisFile >= onFileStruct->bytesDownloadedForThisFile);
  39. printf("%i. (100%%) %i/%i %s %ib / %ib\n", onFileStruct->setID, onFileStruct->fileIndex+1, onFileStruct->numberOfFilesInThisSet, onFileStruct->fileName, onFileStruct->byteLengthOfThisFile, onFileStruct->byteLengthOfThisSet);
  40. // Return true to have RakNet delete the memory allocated to hold this file.
  41. // False if you hold onto the memory, and plan to delete it yourself later
  42. return true;
  43. }
  44. virtual void OnFileProgress(FileProgressStruct *fps)
  45. {
  46. assert(fps->onFileStruct->byteLengthOfThisFile >= fps->onFileStruct->bytesDownloadedForThisFile);
  47. printf("%i (%i%%) %i/%i %s %ib / %ib\n", fps->onFileStruct->setID, (int) (100.0*(double)fps->partCount/(double)fps->partTotal),
  48. fps->onFileStruct->fileIndex+1,
  49. fps->onFileStruct->numberOfFilesInThisSet,
  50. fps->onFileStruct->fileName,
  51. fps->onFileStruct->byteLengthOfThisFile,
  52. fps->onFileStruct->byteLengthOfThisSet,
  53. fps->firstDataChunk);
  54. }
  55. virtual bool OnDownloadComplete(DownloadCompleteStruct *dcs)
  56. {
  57. printf("Download complete.\n");
  58. // Returning false automatically deallocates the automatically allocated handler that was created by DirectoryDeltaTransfer
  59. return false;
  60. }
  61. } transferCallback;
  62. int main(void)
  63. {
  64. char ch;
  65. #ifdef USE_TCP
  66. RakNet::PacketizedTCP tcp1;
  67. #else
  68. RakNet::RakPeerInterface *rakPeer;
  69. #endif
  70. // directoryDeltaTransfer is the main plugin that does the work for this sample.
  71. RakNet::DirectoryDeltaTransfer directoryDeltaTransfer;
  72. // The fileListTransfer plugin is used by the DirectoryDeltaTransfer plugin and must also be registered (you could use this yourself too if you wanted, of course).
  73. RakNet::FileListTransfer fileListTransfer;
  74. // Read files in parts, rather than the whole file from disk at once
  75. RakNet::IncrementalReadInterface iri;
  76. directoryDeltaTransfer.SetDownloadRequestIncrementalReadInterface(&iri, 1000000);
  77. #ifdef USE_TCP
  78. tcp1.AttachPlugin(&directoryDeltaTransfer);
  79. tcp1.AttachPlugin(&fileListTransfer);
  80. #else
  81. rakPeer = RakNet::RakPeerInterface::GetInstance();
  82. rakPeer->AttachPlugin(&directoryDeltaTransfer);
  83. rakPeer->AttachPlugin(&fileListTransfer);
  84. // Get download progress notifications. Handled by the plugin.
  85. rakPeer->SetSplitMessageProgressInterval(100);
  86. #endif
  87. directoryDeltaTransfer.SetFileListTransferPlugin(&fileListTransfer);
  88. printf("This sample demonstrates the plugin to incrementally transfer compressed\n");
  89. printf("deltas of directories. In essence, it's a simple autopatcher.\n");
  90. printf("Unlike the full autopatcher, it has no dependencies. It is suitable for\n");
  91. printf("patching from non-dedicated servers at runtime.\n");
  92. printf("Difficulty: Intermediate\n\n");
  93. printf("Enter listen port. Enter for default. If running two instances on the\nsame computer, use 0 for the client.\n");
  94. unsigned short localPort;
  95. char str[256];
  96. Gets(str, sizeof(str));
  97. if (str[0]==0)
  98. localPort=60000;
  99. else
  100. localPort=atoi(str);
  101. RakNet::SocketDescriptor socketDescriptor(localPort,0);
  102. #ifdef USE_TCP
  103. bool b=tcp1.Start(localPort,8);
  104. RakAssert(b);
  105. #else
  106. if (rakPeer->Startup(8,&socketDescriptor, 1)!=RakNet::RAKNET_STARTED)
  107. {
  108. RakNet::RakPeerInterface::DestroyInstance(rakPeer);
  109. printf("RakNet initialize failed. Possibly duplicate port.\n");
  110. return 1;
  111. }
  112. rakPeer->SetMaximumIncomingConnections(8);
  113. #endif
  114. printf("Commands:\n");
  115. printf("(S)et application directory.\n");
  116. printf("(A)dd allowed uploads from subdirectory.\n");
  117. printf("(D)ownload from subdirectory.\n");
  118. printf("(C)lear allowed uploads.\n");
  119. printf("C(o)nnect to another system.\n");
  120. printf("(Q)uit.\n");
  121. RakNet::SystemAddress sysAddrZero=RakNet::UNASSIGNED_SYSTEM_ADDRESS;
  122. RakNet::TimeMS nextStatTime = RakNet::GetTimeMS() + 1000;
  123. RakNet::Packet *p;
  124. while (1)
  125. {
  126. /*
  127. if (//directoryDeltaTransfer.GetNumberOfFilesForUpload()>0 &&
  128. RakNet::GetTimeMS() > nextStatTime)
  129. {
  130. // If sending, periodically show connection stats
  131. char statData[2048];
  132. RakNetStatistics *statistics = rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0));
  133. // if (statistics->messagesOnResendQueue>0 || statistics->internalOutputQueueSize>0)
  134. if (rakPeer->GetSystemAddressFromIndex(0)!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  135. {
  136. StatisticsToString(statistics, statData, 2);
  137. printf("%s\n", statData);
  138. }
  139. nextStatTime=RakNet::GetTimeMS()+5000;
  140. }
  141. */
  142. // Process packets
  143. #ifdef USE_TCP
  144. p=tcp1.Receive();
  145. #else
  146. p=rakPeer->Receive();
  147. #endif
  148. #ifdef USE_TCP
  149. RakNet::SystemAddress sa;
  150. sa=tcp1.HasNewIncomingConnection();
  151. if (sa!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  152. {
  153. printf("ID_NEW_INCOMING_CONNECTION\n");
  154. sysAddrZero=sa;
  155. }
  156. if (tcp1.HasLostConnection()!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  157. printf("ID_DISCONNECTION_NOTIFICATION\n");
  158. if (tcp1.HasFailedConnectionAttempt()!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  159. printf("ID_CONNECTION_ATTEMPT_FAILED\n");
  160. sa=tcp1.HasCompletedConnectionAttempt();
  161. if (sa!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  162. {
  163. printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
  164. sysAddrZero=sa;
  165. }
  166. #endif
  167. while (p)
  168. {
  169. #ifdef USE_TCP
  170. tcp1.DeallocatePacket(p);
  171. tcp1.Receive();
  172. #else
  173. if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
  174. {
  175. printf("ID_NEW_INCOMING_CONNECTION\n");
  176. sysAddrZero=p->systemAddress;
  177. }
  178. else if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
  179. {
  180. printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
  181. sysAddrZero=p->systemAddress;
  182. }
  183. else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION)
  184. printf("ID_DISCONNECTION_NOTIFICATION\n");
  185. else if (p->data[0]==ID_CONNECTION_LOST)
  186. printf("ID_CONNECTION_LOST\n");
  187. else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED)
  188. printf("ID_CONNECTION_ATTEMPT_FAILED\n");
  189. rakPeer->DeallocatePacket(p);
  190. p=rakPeer->Receive();
  191. #endif
  192. }
  193. if (kbhit())
  194. {
  195. ch=getch();
  196. if (ch=='s')
  197. {
  198. printf("Enter application directory\n");
  199. Gets(str, sizeof(str));
  200. if (str[0]==0)
  201. strcpy(str, "C:/Temp");
  202. directoryDeltaTransfer.SetApplicationDirectory(str);
  203. printf("This directory will be prefixed to upload and download subdirectories.\n");
  204. }
  205. else if (ch=='a')
  206. {
  207. printf("Enter uploads subdirectory\n");
  208. Gets(str, sizeof(str));
  209. directoryDeltaTransfer.AddUploadsFromSubdirectory(str);
  210. printf("%i files for upload.\n", directoryDeltaTransfer.GetNumberOfFilesForUpload());
  211. }
  212. else if (ch=='d')
  213. {
  214. char subdir[256];
  215. char outputSubdir[256];
  216. printf("Enter remote subdirectory to download from.\n");
  217. printf("This directory may be any uploaded directory, or a subdir therein.\n");
  218. Gets(subdir,sizeof(subdir));
  219. printf("Enter subdirectory to output to.\n");
  220. Gets(outputSubdir,sizeof(outputSubdir));
  221. unsigned short setId;
  222. setId=directoryDeltaTransfer.DownloadFromSubdirectory(subdir, outputSubdir, true, sysAddrZero, &transferCallback, HIGH_PRIORITY, 0, 0);
  223. if (setId==(unsigned short)-1)
  224. printf("Download failed. Host unreachable.\n");
  225. else
  226. printf("Downloading set %i\n", setId);
  227. }
  228. else if (ch=='c')
  229. {
  230. directoryDeltaTransfer.ClearUploads();
  231. printf("Uploads cleared.\n");
  232. }
  233. else if (ch=='o')
  234. {
  235. char host[256];
  236. printf("Enter host IP: ");
  237. Gets(host,sizeof(host));
  238. if (host[0]==0)
  239. strcpy(host, "127.0.0.1");
  240. unsigned short remotePort;
  241. printf("Enter host port: ");
  242. Gets(str, sizeof(str));
  243. if (str[0]==0)
  244. remotePort=60000;
  245. else
  246. remotePort=atoi(str);
  247. #ifdef USE_TCP
  248. tcp1.Connect(host,remotePort,false);
  249. #else
  250. rakPeer->Connect(host, remotePort, 0, 0);
  251. #endif
  252. printf("Connecting.\n");
  253. }
  254. else if (ch=='q')
  255. {
  256. printf("Bye!\n");
  257. #ifdef USE_TCP
  258. tcp1.Stop();
  259. #else
  260. rakPeer->Shutdown(1000,0);
  261. #endif
  262. break;
  263. }
  264. }
  265. // Keeps the threads responsive
  266. RakSleep(0);
  267. }
  268. #ifdef USE_TCP
  269. #else
  270. RakNet::RakPeerInterface::DestroyInstance(rakPeer);
  271. #endif
  272. return 0;
  273. }
粤ICP备19079148号