SOCKCLI.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

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