home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winsock / iocomplt / sockcli.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  344 lines

  1.  
  2. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. // PARTICULAR PURPOSE.
  6. //
  7. // Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
  8. //
  9. //  MODULE:   sockcli.c
  10. //
  11. //  PURPOSE:  Generate a simulated load for a sockets server.
  12. //
  13. //  FUNCTIONS:
  14. //     main           - Entry point for the program.
  15. //     CompleteBenchmark - Work routine for communication with server.
  16. //     ShowUsage       - Display usage help.
  17. //     ParseSwitch       - Process a command line argument.
  18. //
  19. //  COMMENTS:
  20. //
  21. //
  22.  
  23. #include "sockcli.h"
  24.  
  25.  
  26. int _CRTAPI1
  27. main (
  28.         int argc,
  29.         char *argv[],
  30.         char *envp[]
  31. )
  32. {
  33.  
  34.    char chChar, *pchChar;
  35.    INT err;
  36.    WSADATA WsaData;
  37.  
  38.    fVerbose = FALSE;
  39.    dwIterations = 1000;
  40.    dwTransferSize = 512;
  41.    fRandom = FALSE;
  42.  
  43.    //
  44.    // Initialize Windows Sockets and request version 1.1
  45.    //
  46.    err = WSAStartup (0x0101, &WsaData);
  47.    if (err == SOCKET_ERROR)
  48.    {
  49.       fprintf (stdout, "WSAStartup() failed: %ld\n", GetLastError ());
  50.       return 1;
  51.    }
  52.  
  53.    //
  54.    // Default to the loopback address for the Benchmark
  55.    //
  56.    RemoteIpAddress.s_addr = htonl (INADDR_LOOPBACK);
  57.  
  58.    while (--argc)
  59.    {
  60.       pchChar = *++argv;
  61.       if (*pchChar == '/' || *pchChar == '-')
  62.       {
  63.          while (chChar = *++pchChar)
  64.          {
  65.             ParseSwitch (chChar, &argc, &argv);
  66.          }
  67.       }
  68.    }
  69.  
  70.    CompleteBenchmark ();
  71.  
  72.    return 1;
  73. }
  74.  
  75.  
  76. VOID
  77. WINAPI
  78. CompleteBenchmark (
  79.                      VOID
  80. )
  81. {
  82.    SOCKET s;
  83.    SOCKADDR_IN remoteAddr;
  84.    INT err;
  85.    INT bytesReceived;
  86.    DWORD i;
  87.    DWORD startTime;
  88.    DWORD endTime;
  89.    DWORD totalTime;
  90.    DWORD thisTransferSize;
  91.    DWORD bytesTransferred = 0;
  92.    INT ReceiveBufferSize;
  93.    INT SendBufferSize;
  94.  
  95.    ReceiveBufferSize = CLIENT_OUTBOUND_BUFFER_MAX;
  96.    SendBufferSize = sizeof (CLIENT_IO_BUFFER);
  97.  
  98.    //
  99.    // Open a socket using the Internet Address family and TCP
  100.    //
  101.    s = socket (AF_INET, SOCK_STREAM, 0);
  102.    if (s == INVALID_SOCKET)
  103.    {
  104.       printf ("DoEcho: socket failed: %ld\n", GetLastError ());
  105.    }
  106.  
  107.    //
  108.    // Set the receive buffer size...
  109.    //
  110.    err = setsockopt (s, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, sizeof (ReceiveBufferSize));
  111.    if (err == SOCKET_ERROR)
  112.    {
  113.       printf ("DoEcho: setsockopt( SO_RCVBUF ) failed: %ld\n", GetLastError ());
  114.       closesocket (s);
  115.       return;
  116.    }
  117.  
  118.    //
  119.    // ...and the send buffer size for our new socket
  120.    //
  121.    err = setsockopt (s, SOL_SOCKET, SO_SNDBUF, (char *) &SendBufferSize, sizeof (SendBufferSize));
  122.    if (err == SOCKET_ERROR)
  123.    {
  124.       printf ("DoEcho: setsockopt( SO_SNDBUF ) failed: %ld\n", GetLastError ());
  125.       closesocket (s);
  126.       return;
  127.    }
  128.  
  129.  
  130.    //
  131.    // Connect to an agreed upon port on the host.  See the
  132.    // commdef.h file for the actual port number
  133.    //
  134.    ZeroMemory (&remoteAddr, sizeof (remoteAddr));
  135.  
  136.    remoteAddr.sin_family = AF_INET;
  137.    remoteAddr.sin_port = htons (SERVPORT);
  138.    remoteAddr.sin_addr = RemoteIpAddress;
  139.  
  140.    err = connect (s, (PSOCKADDR) & remoteAddr, sizeof (remoteAddr));
  141.    if (err == SOCKET_ERROR)
  142.    {
  143.       printf ("DoEcho: connect failed: %ld\n", GetLastError ());
  144.       closesocket (s);
  145.       return;
  146.    }
  147.  
  148.  
  149.    for (i = 0; i < dwIterations; i++)
  150.    {
  151.  
  152.       if (fRandom)
  153.       {
  154.          thisTransferSize = (rand () * dwTransferSize) / RAND_MAX;
  155.       }
  156.       else
  157.       {
  158.          thisTransferSize = dwTransferSize;
  159.       }
  160.  
  161.  
  162.       SendBuffer.MessageType = CLIENT_IO_MT_RETURN_DATA;
  163.       SendBuffer.u.ReturnData.ByteCount = thisTransferSize;
  164.  
  165.       //
  166.       // Send "echo request" to remote host
  167.       //
  168.       err = send (s, (CHAR *) & SendBuffer, sizeof (SendBuffer), 0);
  169.       if (err != sizeof (SendBuffer))
  170.       {
  171.          printf ("send didn't work, ret = %ld, error = %ld\n", err, GetLastError ());
  172.          closesocket (s);
  173.          return;
  174.       }
  175.  
  176.       //
  177.       // Read as much as the remote host should echo
  178.       //
  179.       bytesReceived = 0;
  180.       do
  181.       {
  182.          err = recv (s, ReceiveBuffer, thisTransferSize, 0);
  183.          if (i == 0)
  184.          {
  185.             startTime = GetTickCount ();
  186.          }
  187.          if (err == SOCKET_ERROR)
  188.          {
  189.             printf ("recv failed: %ld\n", GetLastError ());
  190.             closesocket (s);
  191.             return;
  192.          }
  193.          else if (err == 0 && thisTransferSize != 0)
  194.          {
  195.             printf ("socket closed prematurely by remote.\n");
  196.             return;
  197.          }
  198.          bytesReceived += err;
  199.       }
  200.       while (bytesReceived < (INT) thisTransferSize);
  201.  
  202.       bytesTransferred += thisTransferSize;
  203.    }
  204.  
  205.    endTime = GetTickCount ();
  206.    totalTime = endTime - startTime;
  207.  
  208.    //
  209.    // Send final packet to remote host
  210.    //
  211.    SendBuffer.MessageType = CLIENT_IO_MT_I_AM_DONE;
  212.    SendBuffer.u.IAmDone.TotalTicks = totalTime;
  213.    SendBuffer.u.IAmDone.TotalIterations = dwIterations;
  214.    SendBuffer.u.IAmDone.TotalBytesTransferred = bytesTransferred;
  215.  
  216.    send (s, (CHAR *) & SendBuffer, sizeof (SendBuffer), 0);
  217.  
  218.    //
  219.    // Display benchmark summary
  220.    //
  221.    printf ("\n%ld bytes transferred in %ld iterations, time = %ld ms\n",
  222.            bytesTransferred, dwIterations, totalTime);
  223.    printf ("Rate = %ld KB/s, %ld T/S, %ld ms/iteration\n",
  224.            (bytesTransferred / totalTime) * 2,
  225.            (dwIterations * 1000) / totalTime,
  226.            totalTime / dwIterations);
  227.  
  228.    //
  229.    // Close connection to remote host
  230.    //
  231.    err = closesocket (s);
  232.    if (err == SOCKET_ERROR)
  233.    {
  234.       printf ("closesocket failed: %ld\n", GetLastError ());
  235.       return;
  236.    }
  237.  
  238.    return;
  239. }
  240.  
  241.  
  242.  
  243. VOID
  244. WINAPI
  245. ShowUsage (
  246.              VOID
  247. )
  248. {
  249.    fputs ("usage: SOCKCLI [switches]\n"
  250.       "               [-?] show this message\n"
  251.       "               [-r] use random transfer sizes\n"
  252.       "               [-i number-of-iterations] specify the number of iterations\n"
  253.       "               [-s transfer-size] specify the fixed transfer size\n"
  254.       "               [-h hostname] specify the remote server\n"
  255.           ,stderr);
  256.  
  257.    exit (1);
  258. }
  259.  
  260.  
  261.  
  262. VOID
  263. WINAPI
  264. ParseSwitch (
  265.                CHAR chSwitch,
  266.                int *pArgc,
  267.                char **pArgv[]
  268. )
  269. {
  270.    PHOSTENT host;
  271.  
  272.    switch (toupper (chSwitch))
  273.    {
  274.  
  275.    case '?':
  276.       ShowUsage ();
  277.       break;
  278.  
  279.    case 'R':
  280.       fRandom = TRUE;
  281.       srand (22);
  282.       break;
  283.  
  284.  
  285.    case 'I':
  286.       if (!--(*pArgc))
  287.       {
  288.          ShowUsage ();
  289.       }
  290.       (*pArgv)++;
  291.       dwIterations = strtoul (*(*pArgv), NULL, 10);
  292.       break;
  293.  
  294.    case 'S':
  295.       if (!--(*pArgc))
  296.       {
  297.          ShowUsage ();
  298.       }
  299.       (*pArgv)++;
  300.       dwTransferSize = strtoul (*(*pArgv), NULL, 10);
  301.       if (dwTransferSize > CLIENT_OUTBOUND_BUFFER_MAX)
  302.       {
  303.          dwTransferSize = CLIENT_OUTBOUND_BUFFER_MAX;
  304.       }
  305.       fRandom = FALSE;
  306.       break;
  307.  
  308.    case 'H':
  309.       if (!--(*pArgc))
  310.       {
  311.          ShowUsage ();
  312.       }
  313.       (*pArgv)++;
  314.  
  315.       //
  316.       // Assumed host is specified by name
  317.       //
  318.       host = gethostbyname (*(*pArgv));
  319.       if (host == NULL)
  320.       {
  321.          //
  322.          // See if the host is specified in "dot address" form
  323.          //
  324.          RemoteIpAddress.s_addr = inet_addr (*(*pArgv));
  325.          if (RemoteIpAddress.s_addr == -1)
  326.          {
  327.             fprintf (stdout, "Unknown remote host: %s\n", *(*pArgv));
  328.             exit (1);
  329.          }
  330.       }
  331.       else
  332.       {
  333.          CopyMemory ((char *) &RemoteIpAddress, host->h_addr, host->h_length);
  334.       }
  335.       break;
  336.  
  337.    default:
  338.       fprintf (stderr, "SOCKCLI: Invalid switch - /%c\n", chSwitch);
  339.       ShowUsage ();
  340.       break;
  341.  
  342.    }
  343. }
  344.