PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/udptest.cpp

https://github.com/gigablast/open-source-search-engine
C++ | 165 lines | 110 code | 21 blank | 34 comment | 22 complexity | 7a3cf6b9b47861a7ecb417305a5f9d24 MD5 | raw file
Possible License(s): Apache-2.0
  1. // Matt Wells, copyright Sep 2001
  2. #include "gb-include.h"
  3. #include "Mem.h"
  4. #include "Conf.h"
  5. #include "Hostdb.h"
  6. #include "UdpServer.h"
  7. #include "Loop.h"
  8. #include "ip.h"
  9. #include <ctype.h>
  10. #include "Spider.h"
  11. // the default protocol
  12. UdpProtocol g_dp;
  13. // the request handler
  14. static void handleRequest ( UdpSlot *slot , int32_t niceness ) ;
  15. static void gotit ( void *state , UdpSlot *slot ) ;
  16. // where we store the file contents, if any
  17. char s_buf [ 1024*1024 ];
  18. int32_t s_n = 0;
  19. int64_t s_startTime;
  20. bool mainShutdown ( bool urgent ) { return true; }
  21. int main ( int argc , char *argv[] ) {
  22. // ip/port to ask for the file from
  23. int32_t ip = 0;
  24. uint16_t port = 0;
  25. // . filename may be supplied
  26. // . if so we send that file back to all who ask
  27. if ( argc == 2 && !isdigit(argv[1][0]) ) {
  28. char *fn = argv[1];
  29. log("Reading filename = %s", fn );
  30. int fd = open ( fn , O_RDONLY );
  31. if ( fd < 0 ) {
  32. log("File %s does not exist. exiting.",fn );
  33. return -1;
  34. }
  35. s_n = 0;
  36. while ( s_n < 1024*1024 && read ( fd , &s_buf[s_n] , 1 ) == 1)
  37. s_n++;
  38. close ( fd );
  39. // listen on udp port 2000
  40. port = 2000;
  41. //log("Listening on udp port %hu", port );
  42. }
  43. // otherwise if argc is 2 we ask an ip/port for the file
  44. else if ( argc == 2 && isdigit(argv[1][0]) ) {
  45. // send on udp port 2001
  46. port = 2001;
  47. ip = atoip ( argv[1] , gbstrlen(argv[1]) );
  48. }
  49. // otherwise, print usage
  50. else {
  51. fprintf(stderr,
  52. "udptest <filename>\n"
  53. "\tThis will set up a server on udp port 2000 which\n"
  54. "\twill serve the specified filename to all incoming\n"
  55. "\trequests. The first char of the filename must NOT\n"
  56. "\tbe a number.\n\n"
  57. "udptest <ip>\n"
  58. "\tThis will send a request for a file to the\n"
  59. "\tudptest running on the specified ip. ip must be\n"
  60. "\tof form like 1.2.3.4\n"
  61. "\tIt will listen on udp port 2001.\n"
  62. );
  63. return -1;
  64. }
  65. // init our table for doing zobrist hashing
  66. if ( ! hashinit() ) {
  67. log("main::hashinit failed" ); return 1; }
  68. // default conf filename
  69. char *confFilename = "./gigablast.conf";
  70. if ( ! g_conf.init ( confFilename ) ) {
  71. fprintf (stderr,"main::Conf init failed\n" ); return 1; }
  72. // init the memory class after conf since it gets maxMem from Conf
  73. if ( ! g_mem.init ( 1000000000 ) ) {
  74. fprintf (stderr,"main::Mem init failed" ); return 1; }
  75. // start up hostdb
  76. if ( ! g_hostdb.init() ) {
  77. log("main::Hostdb init failed" ); return 1; }
  78. // init the loop
  79. if ( ! g_loop.init() ) {
  80. fprintf ( stderr , "main::Loop init failed\n" );
  81. return 1;
  82. }
  83. // . then our main udp server
  84. // . must pass defaults since g_dns uses it's own port/instance of it
  85. // . server should listen to a socket and register with g_loop
  86. // . the last 1 and 0 are respective niceness levels
  87. if ( ! g_udpServer.init( port , // use 2000 or 2001
  88. &g_dp , // use default proto
  89. 0 , // niceness = 0
  90. 1024*1024 ,
  91. 1024*1024 )){
  92. fprintf ( stderr, "main::UdpServer init failed\n");
  93. return 1;
  94. }
  95. // . otherwise, set up a handler for incoming msgTypes of 0x00
  96. // . register a handler for msgType 0x00
  97. // . we must register this msgType even if we're not going to handle
  98. // these requests, because we may send them...
  99. if ( ! g_udpServer.registerHandler ( 0x00 , handleRequest )) {
  100. fprintf ( stderr , "udp server registration failed\n");
  101. return 1;
  102. }
  103. // if ip is non-zero send a request to it
  104. if ( ip != 0 ) {
  105. log("Sending request to ip=%s port=2000", argv[1] );
  106. s_startTime = gettimeofdayInMilliseconds();
  107. g_udpServer.sendRequest ( NULL , // msg ptr
  108. 0 , // msg size
  109. 0x00 , // msg type
  110. ip , // ip
  111. 2000 , // port
  112. 0 , // hostId (bogus)
  113. NULL , // UdpSlot ptr being used
  114. NULL , // callback state
  115. gotit, // callback
  116. 30 );// timeout in seconds
  117. }
  118. // . now start g_loops main interrupt handling loop
  119. // . it should block forever
  120. // . when it gets a signal it dispatches to a server or db to handle it
  121. if ( ! g_loop.runLoop() ) {
  122. log("main::runLoop failed" );
  123. return 1;
  124. }
  125. // dummy return (0-->normal exit status for the shell)
  126. return 0;
  127. }
  128. void handleRequest ( UdpSlot *slot , int32_t niceness ) {
  129. log("got request of type 0x00");
  130. // send the deisignated file back
  131. g_udpServer.sendReply ( s_buf , // data ptr
  132. s_n , // data size
  133. 0 , // allocated size
  134. slot );
  135. //sendErrorReply ( slot , EBADREQUESTSIZE )
  136. }
  137. void gotit ( void *state , UdpSlot *slot ) {
  138. // compute speed
  139. double size = slot->m_readBufSize;
  140. double elapsed = gettimeofdayInMilliseconds() - s_startTime;
  141. log("got reply. %f Mbps", (size*8/(1024.0*1024.0)) / (elapsed / 1000.0) );
  142. // exit for good
  143. exit(-1);
  144. }