main.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 "RakPeerInterface.h"
  11. #include "FileListTransfer.h"
  12. #include "RakSleep.h"
  13. #include "MessageIdentifiers.h"
  14. #include "FileListTransferCBInterface.h"
  15. #include "FileOperations.h"
  16. #include "SuperFastHash.h"
  17. #include "RakAssert.h"
  18. #include "BitStream.h"
  19. #include "IncrementalReadInterface.h"
  20. #include "PacketizedTCP.h"
  21. #include "SocketLayer.h"
  22. #include <stdio.h>
  23. #include "Gets.h"
  24. RakNet::RakString file;
  25. RakNet::RakString fileCopy;
  26. //const char *file = "c:/temp/unittest.vcproj";
  27. //const char *fileCopy = "c:/temp/unittest_copy.vcproj";
  28. #define USE_TCP
  29. class TestCB : public RakNet::FileListTransferCBInterface
  30. {
  31. public:
  32. bool OnFile(
  33. OnFileStruct *onFileStruct)
  34. {
  35. printf("OnFile: %i. (100%%) %i/%i %s %ib / %ib\n",
  36. onFileStruct->setID,
  37. onFileStruct->fileIndex+1,
  38. onFileStruct->numberOfFilesInThisSet,
  39. onFileStruct->fileName,
  40. onFileStruct->byteLengthOfThisFile,
  41. onFileStruct->byteLengthOfThisSet);
  42. FILE *fp = fopen(fileCopy.C_String(), "wb");
  43. fwrite(onFileStruct->fileData, onFileStruct->byteLengthOfThisFile, 1, fp);
  44. fclose(fp);
  45. // Make sure it worked
  46. unsigned int hash1 = SuperFastHashFile(file.C_String());
  47. if (RakNet::BitStream::DoEndianSwap())
  48. RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash1, sizeof(hash1));
  49. unsigned int hash2 = SuperFastHashFile(fileCopy.C_String());
  50. if (RakNet::BitStream::DoEndianSwap())
  51. RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash2, sizeof(hash2));
  52. RakAssert(hash1==hash2);
  53. // Return true to have RakNet delete the memory allocated to hold this file.
  54. // False if you hold onto the memory, and plan to delete it yourself later
  55. return true;
  56. }
  57. virtual void OnFileProgress(FileProgressStruct *fps)
  58. {
  59. printf("OnFileProgress: %i partCount=%i partTotal=%i (%i%%) %i/%i %s %ib/%ib %ib/%ib total\n",
  60. fps->onFileStruct->setID,
  61. fps->partCount, fps->partTotal, (int) (100.0*(double)fps->onFileStruct->bytesDownloadedForThisFile/(double)fps->onFileStruct->byteLengthOfThisFile),
  62. fps->onFileStruct->fileIndex+1,
  63. fps->onFileStruct->numberOfFilesInThisSet,
  64. fps->onFileStruct->fileName,
  65. fps->onFileStruct->bytesDownloadedForThisFile,
  66. fps->onFileStruct->byteLengthOfThisFile,
  67. fps->onFileStruct->bytesDownloadedForThisSet,
  68. fps->onFileStruct->byteLengthOfThisSet,
  69. fps->firstDataChunk);
  70. }
  71. virtual bool OnDownloadComplete(DownloadCompleteStruct *dcs)
  72. {
  73. printf("Download complete.\n");
  74. // Returning false automatically deallocates the automatically allocated handler that was created by DirectoryDeltaTransfer
  75. return false;
  76. }
  77. } transferCallback;
  78. // Sender progress notification
  79. class TestFileListProgress : public RakNet::FileListProgress
  80. {
  81. virtual void OnFilePush(const char *fileName, unsigned int fileLengthBytes, unsigned int offset, unsigned int bytesBeingSent, bool done, RakNet::SystemAddress targetSystem, unsigned short setID)
  82. {
  83. printf("Sending %s bytes=%i offset=%i\n", fileName, bytesBeingSent, offset);
  84. }
  85. virtual void OnFilePushesComplete( RakNet::SystemAddress systemAddress, unsigned short setID )
  86. {
  87. char str[32];
  88. systemAddress.ToString(true, (char*) str);
  89. RAKNET_DEBUG_PRINTF("File pushes complete to %s\n", str);
  90. }
  91. virtual void OnSendAborted( RakNet::SystemAddress systemAddress )
  92. {
  93. char str[32];
  94. systemAddress.ToString(true, (char*) str);
  95. RAKNET_DEBUG_PRINTF("Send aborted to %s\n", str);
  96. }
  97. } testFileListProgress;
  98. int main()
  99. {
  100. printf("This sample demonstrates incrementally sending a file with\n");
  101. printf("the FileListTransferPlugin. Incremental sends will read and send the.\n");
  102. printf("file only as needed, rather than putting the whole file in memory.\n");
  103. printf("This is to support sending large files to many users at the same time.\n");
  104. printf("Difficulty: Intermediate\n\n");
  105. TestCB testCB;
  106. RakNet::FileListTransfer flt1, flt2;
  107. #ifdef USE_TCP
  108. RakNet::PacketizedTCP tcp1, tcp2;
  109. #if RAKNET_SUPPORT_IPV6==1
  110. const bool testInet6=true;
  111. #else
  112. const bool testInet6=false;
  113. #endif
  114. if (testInet6)
  115. {
  116. tcp1.Start(60000,1,-99999,AF_INET6);
  117. tcp2.Start(60001,1,-99999,AF_INET6);
  118. tcp2.Connect("::1",60000,false,AF_INET6);
  119. }
  120. else
  121. {
  122. tcp1.Start(60000,1,-99999,AF_INET);
  123. tcp2.Start(60001,1,-99999,AF_INET);
  124. tcp2.Connect("127.0.0.1",60000,false,AF_INET);
  125. }
  126. tcp1.AttachPlugin(&flt1);
  127. tcp2.AttachPlugin(&flt2);
  128. #else
  129. RakNet::RakPeerInterface *peer1 = RakNet::RakPeerInterface::GetInstance();
  130. RakNet::RakPeerInterface *peer2 = RakNet::RakPeerInterface::GetInstance();
  131. RakNet::SocketDescriptor sd1(60000,0),sd2(60001,0);
  132. peer1->Startup(1,&sd1,1);
  133. peer2->Startup(1,&sd2,1);
  134. peer1->SetMaximumIncomingConnections(1);
  135. peer2->Connect("127.0.0.1",60000,0,0,0);
  136. peer1->AttachPlugin(&flt1);
  137. peer2->AttachPlugin(&flt2);
  138. peer1->SetSplitMessageProgressInterval(9);
  139. peer2->SetSplitMessageProgressInterval(9);
  140. #endif
  141. // Print sending progress notifications
  142. flt1.AddCallback(&testFileListProgress);
  143. // Run incremental reads in a thread so the read does not block the main thread
  144. flt1.StartIncrementalReadThreads(1);
  145. RakNet::FileList fileList;
  146. RakNet::IncrementalReadInterface incrementalReadInterface;
  147. printf("Enter complete filename with path to test:\n");
  148. char str[256];
  149. Gets(str, sizeof(str));
  150. if (str[0]==0)
  151. strcpy(str, "D:\\RakNet\\Lib\\RakNetLibStaticDebug.lib");
  152. file=str;
  153. fileCopy=file+"_copy";
  154. // Reference this file, rather than add it in memory. Will send 1000 byte chunks. The reason to do this is so the whole file does not have to be in memory at once
  155. unsigned int fileLength = GetFileLength(file.C_String());
  156. if (fileLength==0)
  157. {
  158. printf("Test file %s not found.\n", file.C_String());
  159. #ifdef USE_TCP
  160. #else
  161. RakNet::RakPeerInterface::DestroyInstance(peer1);
  162. RakNet::RakPeerInterface::DestroyInstance(peer2);
  163. #endif
  164. return 1;
  165. }
  166. fileList.AddFile(file.C_String(), file.C_String(), 0, fileLength, fileLength, FileListNodeContext(0,0,0,0), true);
  167. // Wait for the connection
  168. printf("File added.\n");
  169. RakSleep(100);
  170. RakNet::Packet *packet1, *packet2;
  171. while (1)
  172. {
  173. #ifdef USE_TCP
  174. RakNet::SystemAddress sa;
  175. sa=tcp2.HasCompletedConnectionAttempt();
  176. if (sa!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  177. {
  178. flt2.SetupReceive(&testCB, false, sa);
  179. break;
  180. }
  181. #else
  182. // Wait for the connection request to be accepted
  183. packet2=peer2->Receive();
  184. if (packet2 && packet2->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
  185. {
  186. flt2.SetupReceive(&testCB, false, packet2->systemAddress);
  187. peer2->DeallocatePacket(packet2);
  188. break;
  189. }
  190. peer2->DeallocatePacket(packet2);
  191. #endif
  192. RakSleep(30);
  193. }
  194. // When connected, send the file. Since the file is a reference, it will be sent incrementally
  195. while (1)
  196. {
  197. #ifdef USE_TCP
  198. packet1=tcp1.Receive();
  199. packet2=tcp2.Receive();
  200. RakNet::SystemAddress sa;
  201. sa = tcp1.HasNewIncomingConnection();
  202. if (sa!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  203. flt1.Send(&fileList,0,sa,0,HIGH_PRIORITY,0, &incrementalReadInterface, 2000 * 1024);
  204. tcp1.DeallocatePacket(packet1);
  205. tcp2.DeallocatePacket(packet2);
  206. #else
  207. packet1=peer1->Receive();
  208. packet2=peer2->Receive();
  209. if (packet1 && packet1->data[0]==ID_NEW_INCOMING_CONNECTION)
  210. flt1.Send(&fileList,peer1,packet1->systemAddress,0,HIGH_PRIORITY,0, &incrementalReadInterface, 2000000);
  211. peer1->DeallocatePacket(packet1);
  212. peer2->DeallocatePacket(packet2);
  213. #endif
  214. RakSleep(0);
  215. }
  216. #ifdef USE_TCP
  217. #else
  218. RakNet::RakPeerInterface::DestroyInstance(peer1);
  219. RakNet::RakPeerInterface::DestroyInstance(peer1);
  220. #endif
  221. return 0;
  222. }
粤ICP备19079148号