test_ncbi_namedpipe.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_ncbi_namedpipe.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:46:09  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_ncbi_namedpipe.cpp,v 1000.1 2004/06/01 18:46:09 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Vladimir Ivanov, Anton Lavrentiev
  35.  *
  36.  * File Description:  Test program for CNamedPipe[Client|Server] classes
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbiapp.hpp>
  41. #include <corelib/ncbienv.hpp>
  42. #include <corelib/ncbiargs.hpp>
  43. #include <corelib/ncbifile.hpp>
  44. #include <corelib/ncbi_system.hpp>
  45. #include <connect/ncbi_namedpipe.hpp>
  46. #include <test/test_assert.h>  // This header must go last
  47. USING_NCBI_SCOPE;
  48. // Test pipe name
  49. #if defined(NCBI_OS_MSWIN)
  50.     const string  kPipeName = "\\.\pipe\ncbi\test_pipename";
  51. #elif defined(NCBI_OS_UNIX)
  52.     const string  kPipeName = "./.ncbi_test_pipename";
  53. #endif
  54. const size_t kNumSubBlobs = 10;
  55. const size_t kSubBlobSize = 10*1024;
  56. const size_t kBlobSize    = kNumSubBlobs * kSubBlobSize;
  57. ////////////////////////////////
  58. // Auxiliary functions
  59. //
  60. // Reading from pipe
  61. static EIO_Status s_ReadPipe(CNamedPipe& pipe, void* buf, size_t size,
  62.                              size_t* n_read) 
  63. {
  64.     size_t     n_read_total = 0;
  65.     size_t     x_read       = 0;
  66.     EIO_Status status;
  67.     
  68.     do {
  69.         status = pipe.Read((char*)buf + n_read_total,
  70.                            size - n_read_total, &x_read);
  71.         LOG_POST("Read from pipe "+ NStr::UIntToString(x_read) + " bytes");
  72.         n_read_total += x_read;
  73.     } while (status == eIO_Success  &&  n_read_total < size);
  74.     
  75.     if (status == eIO_Timeout) {
  76.      status = eIO_Success;
  77.     }
  78.     *n_read = n_read_total;
  79.     return status;
  80. }
  81. // Writing to pipe
  82. static EIO_Status s_WritePipe(CNamedPipe& pipe, const void* buf, size_t size,
  83.                               size_t* n_written) 
  84. {
  85.     size_t     n_written_total = 0;
  86.     size_t     x_written       = 0;
  87.     EIO_Status status;
  88.     
  89.     do {
  90.         status = pipe.Write((char*)buf + n_written_total,
  91.                            size - n_written_total, &x_written);
  92.         LOG_POST("Write to pipe "+ NStr::UIntToString(x_written) + " bytes");
  93.         n_written_total += x_written;
  94.     } while (status == eIO_Success  &&  n_written_total < size);
  95.     
  96.     if (status == eIO_Timeout) {
  97.      status = eIO_Success;
  98.     }
  99.     *n_written = n_written_total;
  100.     return status;
  101. }
  102. ////////////////////////////////
  103. // Test application
  104. //
  105. class CTest : public CNcbiApplication
  106. {
  107. public:
  108.     virtual void Init(void);
  109.     virtual int  Run(void);
  110. private:
  111.     void Client(int num);
  112.     void Server(void);
  113. private:
  114.     string m_PipeName;
  115. };
  116. void CTest::Init(void)
  117. {
  118.     // Set error posting and tracing on maximum
  119.     SetDiagTrace(eDT_Enable);
  120.     SetDiagPostFlag(eDPF_All);
  121.     UnsetDiagPostFlag(eDPF_Line);
  122.     UnsetDiagPostFlag(eDPF_File);
  123.     UnsetDiagPostFlag(eDPF_LongFilename);
  124.     SetDiagPostLevel(eDiag_Info);
  125.     // Create command-line argument descriptions class
  126.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  127.     // Specify USAGE context
  128.     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
  129.                               "Test named pipes API");
  130.     // Describe the expected command-line arguments
  131.     arg_desc->AddPositional 
  132.         ("mode", "Test mode",
  133.          CArgDescriptions::eString);
  134.     arg_desc->SetConstraint
  135.         ("mode", &(*new CArgAllow_Strings, "client", "server"));
  136.     arg_desc->AddDefaultPositional
  137.         ("postfix", "Unique string that will be added to the base pipe name",
  138.          CArgDescriptions::eString, "");
  139.     // Setup arg.descriptions for this application
  140.     SetupArgDescriptions(arg_desc.release());
  141. }
  142. int CTest::Run(void)
  143. {
  144.     CArgs args = GetArgs();
  145.     m_PipeName = kPipeName;
  146.     if ( !args["postfix"].AsString().empty() ) {
  147.         m_PipeName += "_" + args["postfix"].AsString();
  148.     }
  149.     LOG_POST("Used pipe name: " + m_PipeName);
  150.     if (args["mode"].AsString() == "client") {
  151.         SetDiagPostPrefix("Client");
  152.         for (int i=1; i<=3; i++) {
  153.             Client(i);
  154.         }
  155.     }
  156.     else if (args["mode"].AsString() == "server") {
  157.         SetDiagPostPrefix("Server");
  158.         Server();
  159.     }
  160.     else {
  161.         _TROUBLE;
  162.     }
  163.     return 0;
  164. }
  165. /////////////////////////////////
  166. // Named pipe client
  167. //
  168. void CTest::Client(int num)
  169. {
  170.     LOG_POST("nStart client " + NStr::IntToString(num) + "...n");
  171.     STimeout timeout = {2,0};
  172.     CNamedPipeClient pipe;
  173.     assert(pipe.IsClientSide());
  174.     assert(pipe.SetTimeout(eIO_Open,  &timeout) == eIO_Success);
  175.     assert(pipe.SetTimeout(eIO_Read,  &timeout) == eIO_Success);
  176.     assert(pipe.SetTimeout(eIO_Write, &timeout) == eIO_Success);
  177.     assert(pipe.Open(m_PipeName,kDefaultTimeout,kSubBlobSize) == eIO_Success);
  178.     char buf[kSubBlobSize];
  179.     size_t n_read    = 0;
  180.     size_t n_written = 0;
  181.     // "Hello" test
  182.     {{
  183.         assert(s_WritePipe(pipe, "Hello", 5, &n_written) == eIO_Success);
  184.         assert(n_written == 5);
  185.         assert(s_ReadPipe(pipe, buf, 2, &n_read) == eIO_Success);
  186.         assert(n_read == 2);
  187.         assert(memcmp(buf, "OK", 2) == 0);
  188.     }}
  189.     // Big binary blob test
  190.     {{
  191.         // Send a very big binary blob
  192.         size_t i;
  193.         unsigned char* blob = (unsigned char*) malloc(kBlobSize);
  194.         for (i = 0; i < kBlobSize; blob[i] = (unsigned char) i, i++); 
  195.         for (i = 0; i < kNumSubBlobs; i++) {
  196.             assert(s_WritePipe(pipe, blob + i*kSubBlobSize, kSubBlobSize,
  197.                                &n_written) == eIO_Success);
  198.             assert(n_written == kSubBlobSize);
  199.         }
  200.         // Receive back a very big binary blob
  201.         memset(blob, 0, kBlobSize);
  202.         for (i = 0;  i < kNumSubBlobs; i++) {
  203.             assert(s_ReadPipe(pipe, blob + i*kSubBlobSize, kSubBlobSize,
  204.                               &n_read) == eIO_Success);
  205.             assert(n_read == kSubBlobSize);
  206.         }
  207.         // Check its content
  208.         for (i = 0; i < kBlobSize; i++) {
  209.             assert(blob[i] == (unsigned char)i);
  210.         }
  211.         free(blob);
  212.         LOG_POST("Blob test is OK...");
  213.     }}
  214. }
  215. /////////////////////////////////
  216. // Named pipe server
  217. //
  218. void CTest::Server(void)
  219. {
  220.     LOG_POST("nStart server...n");
  221. #if defined(NCBI_OS_UNIX)
  222.     // Remove the pipe if it is already exists
  223.     CFile(m_PipeName).Remove();
  224. #endif  
  225.     char buf[kSubBlobSize];
  226.     size_t   n_read    = 0;
  227.     size_t   n_written = 0;
  228.     STimeout timeout   = {30,0};
  229.     CNamedPipeServer pipe(m_PipeName, &timeout, kSubBlobSize + 512);
  230.     assert(pipe.IsServerSide());
  231.     assert(pipe.SetTimeout(eIO_Read,  &timeout) == eIO_Success);
  232.     assert(pipe.SetTimeout(eIO_Write, &timeout) == eIO_Success);
  233.     for (;;) {
  234.         LOG_POST("Listening pipe...");
  235.         EIO_Status status = pipe.Listen();
  236.         switch (status) {
  237.         case eIO_Success:
  238.             LOG_POST("Client is connected...");
  239.             // "Hello" test
  240.             {{
  241.                 assert(s_ReadPipe(pipe, buf, 5 , &n_read) == eIO_Success);
  242.                 assert(n_read == 5);
  243.                 assert(memcmp(buf, "Hello", 5) == 0);
  244.                 assert(s_WritePipe(pipe, "OK", 2, &n_written) == eIO_Success);
  245.                 assert(n_written == 2);
  246.             }}
  247.             // Big binary blob test
  248.             {{
  249.                 // Receive a very big binary blob
  250.                 size_t i;
  251.                 unsigned char* blob = (unsigned char*) malloc(kBlobSize);
  252.                 for (i = 0;  i < kNumSubBlobs; i++) {
  253.                     assert(s_ReadPipe(pipe, blob + i*kSubBlobSize,
  254.                                       kSubBlobSize, &n_read) == eIO_Success);
  255.                     assert(n_read == kSubBlobSize);
  256.                 }
  257.  
  258.                 // Check its content
  259.                 for (i = 0; i < kBlobSize; i++) {
  260.                     assert(blob[i] == (unsigned char)i);
  261.                 }
  262.                 // Write back a received big blob
  263.                 for (i = 0; i < kNumSubBlobs; i++) {
  264.                     assert(s_WritePipe(pipe, blob + i*kSubBlobSize,
  265.                                        kSubBlobSize, &n_written)
  266.                            == eIO_Success);
  267.                     assert(n_written == kSubBlobSize);
  268.                 }
  269.                 memset(blob, 0, kBlobSize);
  270.                 free(blob);
  271.                 LOG_POST("Blob test is OK...");
  272.             }}
  273.             LOG_POST("Disconnect client...");
  274.             assert(pipe.Disconnect() == eIO_Success);
  275.             break;
  276.         case eIO_Timeout:
  277.             LOG_POST("Timeout detected...");
  278.             break;
  279.         default:
  280.             _TROUBLE;
  281.         }
  282.     }
  283. }
  284. ///////////////////////////////////
  285. // APPLICATION OBJECT  and  MAIN
  286. //
  287. int main(int argc, const char* argv[])
  288. {
  289.     // Execute main application function
  290.     return CTest().AppMain(argc, argv, 0, eDS_Default, 0);
  291. }
  292. /*
  293.  * ===========================================================================
  294.  * $Log: test_ncbi_namedpipe.cpp,v $
  295.  * Revision 1000.1  2004/06/01 18:46:09  gouriano
  296.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  297.  *
  298.  * Revision 1.7  2004/05/19 15:29:57  ivanov
  299.  * Added additional cmd line parameter to create unique pipe name
  300.  *
  301.  * Revision 1.6  2004/05/17 20:58:22  gorelenk
  302.  * Added include of PCH ncbi_pch.hpp
  303.  *
  304.  * Revision 1.5  2003/09/04 19:13:43  ivanov
  305.  * Added loop for read/write operations
  306.  *
  307.  * Revision 1.4  2003/09/02 19:54:25  ivanov
  308.  * Changed name of the test pipe. Remove test pipe if it is already exists.
  309.  * Increased default timeout to 2 sec.
  310.  *
  311.  * Revision 1.3  2003/08/25 16:40:45  lavr
  312.  * Get rid of CNamedPipe:: prefix in kDefaultTimeout
  313.  *
  314.  * Revision 1.2  2003/08/20 14:24:06  ivanov
  315.  * Replaced _TRACE with LOG_POST
  316.  *
  317.  * Revision 1.1  2003/08/18 19:23:07  ivanov
  318.  * Initial revision
  319.  *
  320.  * ===========================================================================
  321.  */