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 / appletalk / prperf.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  31KB  |  1,191 lines

  1. /*++
  2.  
  3. Copyright (c) 1994-1997  Microsoft Corporation
  4.  
  5. Module Name: prperf.c
  6.  
  7.  
  8. Abstract: This Sample Windows Socket Application demonstrates use of
  9.           the AppleTalk PAP Protocol. Both a server and a client
  10.           application are included in this source file. The client
  11.           app reads a file and sends the contents to the server. The
  12.           server writes out the received bytes to another file.
  13.  
  14.  
  15. --*/
  16.  
  17. #include <windows.h>
  18.  
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <time.h>
  24.  
  25. //
  26. // the following header contains appletalk specific definitions.
  27. // should be included for AppleTalk Windows Socket Applications
  28. //
  29. #include <atalkwsh.h>
  30. #include "prsamp.h"
  31.  
  32. #define SOCKET_COUNT                    32
  33.  
  34. #define DEF_SERVER_NAME                 "Windows Adsp"
  35. #define DEF_SERVER_TYPE                 "Windows Sockets"
  36. #define DEF_SERVER_ZONE                 "*"
  37. #define BLOCKSIZE                       4096
  38.  
  39. #define DEF_QUEUE_LEN                   5
  40. #define ENTITY_LEN                      32
  41.  
  42. CHAR    gServerName[ENTITY_LEN]         = DEF_SERVER_NAME;
  43. CHAR    gServerType[ENTITY_LEN]         = DEF_SERVER_TYPE;
  44. CHAR    gServerZone[ENTITY_LEN]         = DEF_SERVER_ZONE;
  45. CHAR    gProtocolName[10]               = "ADSP";
  46. INT     NumTimes                        = 5;
  47. CHAR    gFileName[256];
  48.  
  49. LPSTR   pServerName   = gServerName;
  50. LPSTR   pServerType   = gServerType;
  51. LPSTR   pServerZone   = gServerZone;
  52. LPSTR   pProtocolName = gProtocolName;
  53. LPSTR   pFileName     = gFileName;
  54.  
  55.  
  56. HANDLE  gFileHandle;
  57. WSADATA WsaData;
  58.  
  59. SYSTEMTIME    SystemStartTime;
  60. SYSTEMTIME    SystemEndTime;
  61. FILETIME      FileTime;
  62.  
  63. BOOL fFileSpecified = FALSE;
  64. BOOL fVerify = FALSE;
  65. BOOL fRandom = FALSE;
  66. BOOL fRDM    = FALSE;
  67.  
  68. int loop = 1, looptot;
  69. double Throughput, AvgThroughPut, MinThroughPut, MaxThroughPut;
  70.  
  71. CHAR DataString[] = {"0123456789abcdefghijklmnopqrstuvwxyz~!@#$%^&*()_+"};
  72.  
  73. #define NANOPOWER    1000000000
  74.  
  75. //#define DEBUG  
  76.  
  77. typedef struct Sock_Info {
  78.    int     sock_typ;
  79.    int     prototyp;
  80.    SOCKET  nsock;
  81. } *PTEST_INFO, test_info;
  82.  
  83. _cdecl main (IN SHORT argc, IN PSZ argv[])
  84. {
  85.  
  86.    register char p;
  87.    register char *ptr;
  88.    int i, r;
  89.    BOOL fClient = FALSE;
  90.    BOOL fServer = FALSE;
  91.  
  92.    for(i = 1; i < argc; i++)
  93.    {
  94.        p = argv[i][0];
  95.  
  96.        if (p == '/' || p == '-')          // option string
  97.        {
  98.            p = argv[i][1];
  99.  
  100.            switch(tolower(p))
  101.            {
  102.                case 'n':
  103.                    ptr = argv[i]+2;
  104.                    if(*ptr == '\0')
  105.                        usage();
  106.                    while(*pServerName++ = *ptr++);
  107.                    break;
  108.                case 't':
  109.                    ptr = argv[i]+2;
  110.                    if(*ptr == '\0')
  111.                        usage();
  112.                    while(*pServerType++ = *ptr++);
  113.                    break;
  114.                case 'z':
  115.                    ptr = argv[i]+2;
  116.                    if(*ptr == '\0')
  117.                        usage();
  118.                    while(*pServerZone++ = *ptr++);
  119.                    break;
  120.                case 's':
  121.                    ptr = argv[i]+2;
  122.                    if(*ptr != '\0')
  123.                        usage();
  124.                    if(fClient == TRUE)
  125.                        usage();
  126.                    fServer = TRUE;
  127.                    break;
  128.                case 'c':
  129.                    ptr = argv[i]+2;
  130.                    if(*ptr != '\0')
  131.                        usage();
  132.                    if(fServer == TRUE)
  133.                        usage();
  134.                    fClient = TRUE;
  135.                    break;
  136.                case 'p':
  137.                    ptr = argv[i]+2;
  138.                    if(*ptr == '\0')
  139.                        usage();
  140.                    while(*pProtocolName++ = *ptr++);
  141.                    break;
  142.                case 'b':
  143.                    ptr=argv[i]+2;
  144.                    if(*ptr == '\0')
  145.                        usage();
  146.                    NumTimes = atoi(ptr);
  147.                    break;
  148.                case 'f':
  149.                    ptr = argv[i]+2;
  150.                    if(*ptr == '\0')
  151.                        usage();
  152.                    while(*pFileName++ = *ptr++);
  153.                    fFileSpecified = TRUE;
  154.                    break;
  155.                case 'l':
  156.                    ptr = argv[i]+2;
  157.                    if(*ptr == '\0')
  158.                        usage();
  159.                    loop = atoi(ptr);
  160.                    break;
  161.                case 'v':
  162.                    ptr = argv[i]+2;
  163.                    if(*ptr != '\0')
  164.                        usage();
  165.                    fVerify = TRUE;
  166.                    break;
  167.                case 'r':
  168.                    ptr = argv[i]+2;
  169.                    if(*ptr != '\0')
  170.                        usage();
  171.                    fRandom = TRUE;
  172.                    break;
  173.                case 'y':
  174.                    ptr = argv[i]+2;
  175.                    if(*ptr != '\0')
  176.                        usage();
  177.                    fRDM = TRUE;
  178.                    break;
  179.                case '?':
  180.                default:
  181.                    usage();
  182.  
  183.            }
  184.        }
  185.        else
  186.        {
  187.            usage();
  188.        }
  189.  
  190.    }
  191.  
  192. #ifdef DEBUG
  193.    printf("Server Name %s\n", gServerName);
  194.    printf("Server Type %s\n", gServerType);
  195.    printf("Server Zone %s\n", gServerZone);
  196. #endif
  197.    printf("%s throughput measurement\n", gProtocolName);
  198.  
  199.    if(stricmp(gProtocolName, "ADSP") && stricmp(gProtocolName, "PAP"))
  200.    {
  201.        printf("Invalid Protocol Specified\n");
  202.        exit(1);
  203.    }
  204.  
  205.  
  206.    if(!(fClient || fServer))
  207.        usage();
  208.  
  209.    r = WSAStartup(0x0101, &WsaData);
  210.    if (r == SOCKET_ERROR)
  211.    {
  212.        printf("Startup failed!\n");
  213.        WSACleanup();
  214.        return(0);
  215.    }
  216.  
  217.    if(fClient)
  218.    {
  219.        BOOL DClnt;
  220.  
  221.        looptot = 0;
  222.        MaxThroughPut = 0;
  223.        AvgThroughPut = 0;
  224.        if(fFileSpecified)
  225.            printf("Ignoring -f option for client.\n");
  226.        while (looptot < loop)
  227.        {
  228.            DClnt = DoClient();
  229.            if(DClnt)
  230.            {
  231.                if ((looptot == 0) || (MinThroughPut > Throughput))
  232.                    MinThroughPut = Throughput;
  233.  
  234.                if (MaxThroughPut < Throughput)
  235.                    MaxThroughPut = Throughput;
  236.  
  237.                AvgThroughPut = ((AvgThroughPut * looptot) + Throughput)
  238.                                / (looptot+1);
  239.                printf("Loop %2d/%d Throughput Cur/Min/Max/Ave :", ++looptot, loop);
  240.                printf(" %6.2f/%6.2f/%6.2f/%6.2f\n\n\n", Throughput,
  241.                                                         MinThroughPut,
  242.                                                         MaxThroughPut,
  243.                                                         AvgThroughPut);
  244.                Throughput = 0.0;
  245.            }
  246.            else
  247.                break;
  248.        }
  249.    }
  250.  
  251.    if(fServer)
  252.        DoServer();
  253.  
  254.    WSACleanup();
  255.    return(0);
  256. }
  257.  
  258.  
  259. /******************************************************************************
  260.  
  261.  Function - DoServer()
  262.  
  263.  Calling Function - main();
  264.  
  265.  Comments - This section of code calls the Server side of the application.
  266.             
  267. ******************************************************************************/
  268.  
  269.  
  270. BOOL DoServer()
  271. {
  272.    BOOL   fRet = FALSE;
  273.  
  274.    do
  275.    {
  276.  
  277. //
  278. // register the name specified on the command line  or use the
  279. // defaults.
  280. //
  281.  
  282.        fRet = OpenSocketRegisterAndListen();
  283.  
  284.  
  285.    }while(FALSE);
  286.  
  287.    return(fRet);
  288.  
  289. }
  290.  
  291.  
  292. /******************************************************************************
  293.  
  294.  Function - OpenSocketRegisterAndListen()
  295.  
  296.  Calling Function - DoServer();
  297.  
  298.  Comments - This section of code controls the Server side of the application.
  299.             
  300. ******************************************************************************/
  301.  
  302. BOOL OpenSocketRegisterAndListen()
  303. {
  304.  
  305.    int                  r = 0;         // return from socket calls
  306.    int                  pass_no = 1;
  307.    BOOL                 fRet = TRUE;
  308.    SOCKET               sock, newsock; // SOCKET descriptor
  309.    SOCKADDR_AT          atalkaddr;     // See atalkwsh.h
  310.    WSH_REGISTER_NAME    nbpname;       // structure for registering NBP name
  311.                                        // see atalkwsh.h
  312.    fd_set               readfds;       // fd_set strutture for select call
  313.    int                  addrlen;
  314.    PTEST_INFO           test;
  315.    int                  sockettype = SOCK_STREAM;
  316.    int                  protocoltype = ATPROTO_ADSP;
  317.    int                  NumBytesRecvd = 0;
  318.    unsigned long        ThreadId;
  319.  
  320.  
  321.  
  322.  
  323.  
  324. //
  325. // open a appletalk socket. The protocol family should be AF_APPLETALK,
  326. // the socket type can be SOCK_STREAM or SOCK_RDM, and the ProtocolType
  327. // for PAP socket must be ATPROTO_PAP. Note that opening a socket does
  328. // not yet create an endpoint on the AppleTalk Protocol. A bind must
  329. // happen before this socket can be used with AppleTalk;
  330. //
  331.  
  332.    do
  333.    {
  334.        if(!stricmp(gProtocolName, "PAP"))
  335.        {
  336.            sockettype = SOCK_RDM;
  337.            protocoltype = ATPROTO_PAP;
  338.        }
  339.        else if (fRDM)
  340.            sockettype = SOCK_RDM;
  341.  
  342.  
  343.        sock = socket(AF_APPLETALK, sockettype, protocoltype);
  344.  
  345.        if(sock == INVALID_SOCKET)
  346.        {
  347.            printf("Open Socket: Error = %ld\n", WSAGetLastError());
  348.            r = -1;
  349.            break;
  350.        }
  351.  
  352.        atalkaddr.sat_socket = 0;
  353.        atalkaddr.sat_family = AF_APPLETALK;
  354.  
  355.        r = bind(sock, (struct sockaddr *)&atalkaddr, sizeof(SOCKADDR_AT));
  356.  
  357.        if(r < 0)
  358.        {
  359.            printf("Bind:Error = %d\n", WSAGetLastError());
  360.            break;
  361.        }
  362.  
  363.        //
  364.        // end point has now been created on the AppleTalk Protocol
  365.        // now register the name that the client will look up.
  366.        //
  367.  
  368.        strcpy(nbpname.ObjectName, gServerName);
  369.        nbpname.ObjectNameLen = strlen(gServerName);
  370.  
  371.        strcpy(nbpname.TypeName, gServerType);
  372.        nbpname.TypeNameLen = strlen(gServerType);
  373.  
  374.        strcpy(nbpname.ZoneName, "*");
  375.        nbpname.ZoneNameLen = strlen("*");
  376.  
  377.        printf("Registering %s:%s@%s\n", nbpname.ObjectName,
  378.                                         nbpname.TypeName,
  379.                                         nbpname.ZoneName);
  380.  
  381.  
  382.        r = setsockopt(sock,                         // socket descriptor
  383.                      SOL_APPLETALK,                 // socket level - always SOL_APPLETALK
  384.                      SO_REGISTER_NAME,              // socket option
  385.                      (char *)&nbpname,              // nbp name structure
  386.                      sizeof(WSH_NBP_NAME));         // size of nbp name structure
  387.  
  388.  
  389.        if(r < 0)
  390.        {
  391.            printf("Register Name: Error = %d\n", WSAGetLastError());
  392.            break;
  393.        }
  394.  
  395.    }while(FALSE);
  396.  
  397.    if(r == SOCKET_ERROR)
  398.    {
  399.        closesocket(sock);
  400.        return(FALSE);
  401.    }
  402.  
  403. //
  404. // Post a listen on this socket. The default queue length is 5
  405. //
  406.  
  407.    r =  listen(sock, DEF_QUEUE_LEN);
  408.  
  409.    if(r < 0)
  410.    {
  411.        printf("Listen:Error = %d\n", WSAGetLastError());
  412.        return FALSE;
  413.    }
  414.  
  415.  
  416. //
  417. // listen is successful. select the socket for reading
  418. //
  419.  
  420.    do
  421.    {
  422.  
  423.        FD_ZERO(&readfds);            // clear set
  424.        FD_SET(sock, &readfds);       // add sock to set
  425.  
  426. //
  427. // this is a blocking select. Select will complete when
  428. // a client connects.
  429. //
  430.  
  431.        r = select(0, &readfds, NULL, NULL, NULL);
  432.  
  433.        if(r == SOCKET_ERROR)
  434.        {
  435.            printf("Select: Error = %d\n", WSAGetLastError());
  436.            fRet = FALSE;
  437.            break;
  438.        }
  439.  
  440.        if ( r == 0)
  441.        {
  442.            printf("Select: no sockets available\n");
  443.            fRet = FALSE;
  444.            break;
  445.        }
  446.  
  447. //
  448. // Accept an incoming request.
  449. //
  450.  
  451.        addrlen = sizeof(SOCKADDR_AT);
  452.        newsock = accept(sock, (struct sockaddr *)&atalkaddr, &addrlen);
  453.  
  454.        if(newsock == INVALID_SOCKET)
  455.        {
  456.            printf("Accept: Socket Error = %d\n", WSAGetLastError());
  457.  
  458.            fRet = FALSE;
  459.            break;
  460.        }
  461.  
  462. #ifdef DEBUG
  463. //       printf("Accept Succeeded\n");
  464. #endif
  465.  
  466.  
  467.        if(r == SOCKET_ERROR)
  468.        {
  469.            fRet = FALSE;
  470.            break;
  471.        }
  472.  
  473.  
  474.        test = (PTEST_INFO) LocalAlloc(LPTR, sizeof(test_info));  
  475.        test->sock_typ = sockettype;
  476.        test->prototyp = protocoltype;
  477.        test->nsock = newsock;
  478.          
  479.        if( ! CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PerfThread,
  480.                             (PTEST_INFO) test, 0, & ThreadId ) )
  481.        {
  482.            fprintf(stderr,"CreateThread NULL 0 PerfThread %d 0 %d 0 %lx",
  483.                         test->sock_typ, test->prototyp, (unsigned long) & ThreadId);
  484.            exit(1);
  485.         }
  486.  
  487.        if (fRet == FALSE)
  488.            break;
  489.  
  490.    }while (TRUE);
  491.  
  492.  
  493.    closesocket(sock);
  494.  
  495.    //
  496.    // send all done
  497.    //
  498.  
  499.    return(TRUE);
  500.  
  501. }
  502.  
  503.  
  504. /******************************************************************************
  505.  
  506.  Function - PerfThread()
  507.  
  508.  Calling Function - OpenSocketRegisterAndListen();
  509.  
  510.  Comments - This section of code controls the Server side Recieve and Verification
  511.             for the application.
  512.             
  513. ******************************************************************************/
  514.  
  515.  
  516. unsigned long PerfThread( PTEST_INFO lpvTest )
  517. {
  518.    int     r;                          // return from socket calls
  519.    int     recvflags = 0;              // see WSARecvEx call
  520.    CHAR    recvbuf[4096];              // recv buffer
  521.    long    blockmode = 1;              // see ioctlsocket call
  522.    BOOL    fRet = TRUE;
  523.    int     NumBytesRecvd = 0, pass_no = 1;
  524.    SOCKET  newsock = lpvTest->nsock;   // SOCKET descriptor
  525.    int     sockettype = lpvTest->sock_typ;
  526.    int     protocoltype = lpvTest->prototyp;
  527.  
  528.    //
  529.    // make socket non blocking. As far as possible, use non
  530.    // blocking sockets to improve performance of app.
  531.    //
  532.    //
  533.  
  534.    r = ioctlsocket(newsock, FIONBIO, &blockmode);
  535.  
  536.    if( r == SOCKET_ERROR)
  537.    {
  538.        printf("ioctlsocket: error = %d\n", WSAGetLastError());
  539.        fRet = FALSE;
  540.        return(FALSE);
  541.    }
  542.  
  543.    do
  544.    {
  545.  
  546.  
  547.        //
  548.        // Prime a Read here. This will enable the receive to complete
  549.        // This is PAP specific. For other AppleTalk protocols -
  550.        // ADSP and DDP a recv can be posted directly
  551.        //
  552.  
  553.        if(!stricmp(gProtocolName, "PAP"))
  554.        {
  555.  
  556.            r = setsockopt(newsock,
  557.                           SOL_APPLETALK,
  558.                           SO_PAP_PRIME_READ,
  559.                           recvbuf,
  560.                           sizeof(recvbuf));
  561.  
  562.            if( r < 0)
  563.            {
  564.                printf("primeread: error = %d\n", WSAGetLastError());
  565.                fRet = FALSE;
  566.                break;
  567.  
  568.            }
  569.        }
  570.  
  571.        fRet = CheckForRecv(newsock);
  572.  
  573.        if(fRet == FALSE)
  574.            break;
  575.  
  576.        r = WSARecvEx(newsock,recvbuf,sizeof(recvbuf), &recvflags);
  577.  
  578.  
  579.        if ((sockettype == SOCK_RDM) && (r < sizeof(recvbuf)))
  580.        {
  581.            printf("Did not receive entire message\n");
  582.            fRet = FALSE;
  583.            break;
  584.        }
  585.  
  586.        if( r == SOCKET_ERROR)
  587.        {
  588.  
  589.            if (WSAGetLastError() == WSAEWOULDBLOCK)
  590.                continue;
  591.            else
  592.            {
  593.                if(WSAGetLastError() == WSAENOTCONN || WSAGetLastError() == WSAEFAULT)
  594.                    break;
  595.                printf("recv: error = %d\n", WSAGetLastError());
  596.                fRet = FALSE;
  597.                break;
  598.            }
  599.  
  600.        }
  601.  
  602. #ifdef DEBUG
  603. //       printf("Recvd %d bytes\n", r);
  604. #endif
  605.  
  606.        if (fVerify)
  607.        {
  608.            int rr, pos = 0;
  609.  
  610.  
  611.            do
  612.            {
  613.                fRet = CheckForSend(newsock);
  614.  
  615.                if (fRet == FALSE)
  616.                {
  617.                    printf("send select error\n");
  618.                    break;
  619.                }
  620.  
  621.                rr = send(newsock, &recvbuf[pos], r-pos, 0);   
  622.                
  623.                if ( rr < 0 )
  624.                {
  625.                    if(WSAGetLastError() == WSAEWOULDBLOCK)
  626.                    {  
  627.                        printf("Send: error = WSAEWOULDBLOCK\n");
  628.                        continue;
  629.                    }
  630.                    else
  631.                    {
  632.                        printf("send: error = %d\n", WSAGetLastError());
  633.                        break;
  634.                    }
  635.  
  636.                }
  637.  
  638. #ifdef DEBUG
  639. //               printf("Bytes Sent %d\n", rr);
  640. #endif
  641.  
  642.                pos += rr;
  643.  
  644.                if (pos >= r)
  645.                    break;
  646.  
  647.            } while(TRUE);
  648.  
  649.        }  // endif Verify
  650.  
  651.  
  652.        NumBytesRecvd += r;
  653.  
  654.        //
  655.        // reset the recv flags for the next WSARecvEx
  656.        //
  657.        recvflags = 0;
  658.  
  659.    }while(TRUE);
  660.  
  661.    printf("Total Number of Bytes Received = %d \n",NumBytesRecvd);
  662.  
  663.    closesocket(newsock);
  664.    LocalFree(lpvTest);
  665.  
  666.    return(TRUE);
  667. }
  668.  
  669. /******************************************************************************
  670.  
  671.  Function - DoClient()
  672.  
  673.  Calling Function - main();
  674.  
  675.  Comments - This section of code controls the Client side of the application.
  676.             
  677. ******************************************************************************/
  678.  
  679. BOOL DoClient()
  680. {
  681.    int                  r = 0;             // return code
  682.    BOOL                 fRet = FALSE;      //
  683.    int                  charcnt;           // count of bytes read from file
  684.    CHAR                 LookupBuffer[512]; // LookUp results return buffer
  685.    PCHAR                ptupleBuffer;
  686.    PWSH_LOOKUP_NAME     pLookup;
  687.    PWSH_NBP_TUPLE       pTempTuple;
  688.    SOCKADDR_AT          ataddress;
  689.    DWORD                WrittenSize;
  690.    SOCKET               clntsock;
  691.    long                 blockmode = 1;          // for ioctlsocket
  692.    int                  BytesTransferred = 0;
  693.    HLOCAL               memhandle;
  694.    LPSTR                DataPtr, DataStartPtr, DataEndPtr;
  695.    DWORD                hourdiff;          //, minutediff, seconddiff;
  696.    double               StartSecond, EndSecond,ElapsedSeconds;
  697.    int                  sockettype = SOCK_STREAM;
  698.    int                  prototype = ATPROTO_ADSP;
  699.    int                  i, rndbuf;
  700.  
  701.    if(!stricmp(gProtocolName, "PAP"))
  702.    {
  703.        sockettype = SOCK_RDM;
  704.        prototype = ATPROTO_PAP;
  705.    }
  706.    else if (fRDM)
  707.        sockettype = SOCK_RDM;
  708.  
  709.    if (fRandom)
  710.        rndbuf = rand() % strlen(DataString) + 1;
  711.    else
  712.        rndbuf = strlen(DataString);
  713.  
  714.    do
  715.    {
  716.        //
  717.        // See socket call in OpenSocketRegisterAndListen for desc
  718.        //
  719.        clntsock = socket(AF_APPLETALK, sockettype, prototype);
  720.  
  721.        if(clntsock == INVALID_SOCKET)
  722.        {
  723.            printf("Open Socket: Error = %ld\n", WSAGetLastError());
  724.            r = -1;
  725.            break;
  726.  
  727.        }
  728.  
  729.        ataddress.sat_socket = 0;
  730.        ataddress.sat_family = AF_APPLETALK;
  731.  
  732.  
  733.        r = bind(clntsock, (struct sockaddr *)&ataddress, sizeof(SOCKADDR_AT));
  734.  
  735.        if(r < 0)
  736.        {
  737.            printf("Bind:Error = %d\n", WSAGetLastError());
  738.            break;
  739.        }
  740.  
  741.        //
  742.        // end point has now been created on the AppleTalk Protocol.
  743.        // lookup the server name.
  744.        //
  745.  
  746.  
  747.        pLookup = (PWSH_LOOKUP_NAME)LookupBuffer;
  748.  
  749.        strcpy(pLookup->LookupTuple.NbpName.ObjectName, gServerName);
  750.        pLookup->LookupTuple.NbpName.ObjectNameLen = strlen(gServerName);
  751.  
  752.        strcpy(pLookup->LookupTuple.NbpName.TypeName,  gServerType);
  753.        pLookup->LookupTuple.NbpName.TypeNameLen = strlen(gServerType);
  754.  
  755.        strcpy(pLookup->LookupTuple.NbpName.ZoneName, gServerZone);
  756.        pLookup->LookupTuple.NbpName.ZoneNameLen = strlen(gServerZone);
  757.  
  758. #ifdef DEBUG
  759.        printf("Looking up %s:%s@%s\n",pLookup->LookupTuple.NbpName.ObjectName,
  760.                                       pLookup->LookupTuple.NbpName.TypeName,
  761.                                       pLookup->LookupTuple.NbpName.ZoneName);
  762. #endif
  763.  
  764.        WrittenSize = sizeof(LookupBuffer);
  765.  
  766.        r = getsockopt(clntsock, SOL_APPLETALK, SO_LOOKUP_NAME,
  767.                       (char*)LookupBuffer,
  768.                       &WrittenSize);
  769.  
  770.        if(r != NO_ERROR)
  771.        {
  772.            printf("getsockopt:error = %d\n", WSAGetLastError());
  773.            break;
  774.  
  775.        }
  776.  
  777.        if (pLookup->NoTuples <= 0)
  778.        {
  779.            printf("LookupName failed - no tuples found\n");
  780.            r=-1;
  781.            break;
  782.        }
  783.  
  784.        ptupleBuffer = (char *)pLookup+sizeof(WSH_LOOKUP_NAME);
  785.        pTempTuple = (PWSH_NBP_TUPLE)ptupleBuffer;
  786.  
  787.        ataddress.sat_family = AF_APPLETALK;
  788.        ataddress.sat_net = pTempTuple[0].Address.Network;
  789.        ataddress.sat_node = pTempTuple[0].Address.Node;
  790.        ataddress.sat_socket = pTempTuple[0].Address.Socket;
  791.  
  792. #ifdef DEBUG
  793.        printf("server address = %lx.%lx.%lx.\n", ataddress.sat_net,
  794.                                                  ataddress.sat_node,
  795.                                                  ataddress.sat_socket);
  796. #endif
  797.  
  798.  
  799.        //
  800.        // lookup succeeded. Use the address in ataddress to connect to the
  801.        // server
  802.        //
  803.  
  804.        r =  connect(clntsock, (struct sockaddr *)&ataddress, sizeof(SOCKADDR_AT));
  805.  
  806.        if(r < 0)
  807.        {
  808.            printf("connect: error = %d\n", WSAGetLastError());
  809.            break;
  810.        }
  811.  
  812. #ifdef DEBUG
  813. //       printf("Connect Succeeded\n");
  814. #endif
  815.  
  816.  
  817.    }while(FALSE);
  818.  
  819.    if(r < 0)
  820.    {
  821.        closesocket(clntsock);
  822.        return(FALSE);
  823.    }
  824.  
  825.    //
  826.    //  Set Socket to non blocking mode
  827.    //
  828.  
  829.    r = ioctlsocket(clntsock, FIONBIO, &blockmode);
  830.  
  831. #ifdef DEBUG
  832. //       printf("ioctlsocket Succeeded\n");
  833. #endif
  834.  
  835.    if( r == SOCKET_ERROR)
  836.    {
  837.        printf("ioctlsocket: error = %d\n", WSAGetLastError());
  838.        return FALSE;
  839.    }
  840.  
  841.    //
  842.    // Fill Up Send Buffer with Data
  843.    //
  844.    memhandle = LocalAlloc(LPTR, BLOCKSIZE);
  845.    if(memhandle == NULL)
  846.    {
  847.        printf("LocalAlloc Failed %d\n", GetLastError());
  848.        return(FALSE);
  849.    }
  850.    DataPtr = LocalLock(memhandle);
  851.    DataStartPtr = DataPtr;
  852.    DataEndPtr = DataPtr + LocalSize(memhandle);
  853.  
  854.    //
  855.    // fill the buffer with Data
  856.    //
  857.    while((DataStartPtr + rndbuf) <= DataEndPtr)
  858.    {
  859.        memcpy(DataStartPtr, DataString,rndbuf);
  860.        DataStartPtr+= rndbuf;
  861.    }
  862.  
  863.    if(DataStartPtr != DataEndPtr)
  864.        memcpy(DataStartPtr, DataString, DataEndPtr-DataStartPtr-1);
  865.  
  866.    *DataEndPtr = '\0';
  867.  
  868.    fRet = CheckForSend(clntsock);
  869.  
  870.    if(fRet == FALSE)
  871.        return FALSE;
  872.  
  873.    GetLocalTime(&SystemStartTime);
  874.  
  875. #ifdef DEBUG
  876.    printf("Data Size = %d\n", lstrlen(DataPtr));
  877. //   printf("Base Data sent: %s\n",DataStartPtr);
  878.    printf("Start Time:%d:%2d:%2d:%2d\t", SystemStartTime.wHour,
  879.                                          SystemStartTime.wMinute,
  880.                                          SystemStartTime.wSecond,
  881.                                          SystemStartTime.wMilliseconds);
  882. #endif
  883.  
  884.    for( i= 0; i < NumTimes; i++)
  885.    {
  886.        //
  887.        // Can I send - CheckForSend calls select to find if we can send
  888.        // without blocking
  889.        //
  890.        DataStartPtr = DataPtr;
  891.  
  892.        do
  893.        {
  894.            fRet = CheckForSend(clntsock);
  895.  
  896.            if(fRet == FALSE)
  897.            {
  898.                printf("send select error\n");
  899.                break;
  900.            }
  901.  
  902.            charcnt = DataEndPtr - DataStartPtr;
  903.  
  904.            if(charcnt == 0)
  905.                break;
  906.  
  907.            r = send(clntsock, DataStartPtr, charcnt, 0);
  908.  
  909.  
  910.            if ( r < 0 )
  911.            {
  912.  
  913.                if(WSAGetLastError() == WSAEWOULDBLOCK)
  914.                {
  915.                    printf("send: wouldblock\n");
  916.                    continue;
  917.                }
  918.                else
  919.                {
  920.                    printf("send: error = %d\n", WSAGetLastError());
  921.                    fRet = FALSE;
  922.                    break;
  923.                }
  924.  
  925.            }
  926.            else
  927.            { 
  928.            
  929. #ifdef DEBUG
  930. //               printf("Sent %d bytes\n",r);
  931. #endif
  932.  
  933.                if ((fVerify) && (DataStartPtr + r == DataEndPtr))
  934.                {
  935.                    CHAR buffer[4096];
  936.                    int recvflag = 0;
  937.                    int rr, pos = 0;
  938.  
  939.            //
  940.            // Prime a Read here. This will enable the receive to complete
  941.            // This is PAP specific. For other AppleTalk protocols -
  942.            // ADSP and DDP a recv can be posted directly
  943.            //
  944.  
  945.                    if(!stricmp(gProtocolName, "PAP"))
  946.                    {
  947.  
  948.                        rr = setsockopt(clntsock,
  949.                                       SOL_APPLETALK,
  950.                                       SO_PAP_PRIME_READ,
  951.                                       buffer,
  952.                                       sizeof(buffer));
  953.  
  954.                        if( rr < 0)
  955.                        {
  956.                            printf("primeread: error = %d\n", WSAGetLastError());
  957.                            fRet = FALSE;
  958.                            break;
  959.                        }
  960.                    }
  961.  
  962.                    do
  963.                    {
  964.  
  965.                        fRet = CheckForRecv(clntsock);
  966.  
  967.                        if(fRet == FALSE)
  968.                            break;
  969.  
  970.                        rr = WSARecvEx(clntsock, &buffer[pos], sizeof(buffer)-pos, &recvflag);
  971.  
  972.                        if( rr == SOCKET_ERROR)
  973.                        {
  974.                            if (WSAGetLastError() == WSAEWOULDBLOCK)
  975.                                continue;
  976.                            else
  977.                            {
  978.                                printf("recv: error = %d\n", WSAGetLastError());
  979.                                fRet = FALSE;
  980.                                break;
  981.                            }
  982.                        }
  983.  
  984.                        pos += rr;
  985.  
  986. #ifdef DEBUG
  987. //                       printf("Recv'd %d bytes\n",rr);
  988. #endif
  989.  
  990.                        if ((recvflag == 0) || (sockettype == SOCK_RDM) || 
  991.                            (pos == sizeof(buffer)))
  992.                            break;
  993.                        recvflag = 0;
  994.  
  995.                    } while(TRUE);
  996.  
  997.  
  998.                    if ((memcmp(DataPtr, buffer, 4096) != 0) && (fRet != FALSE))
  999.                    {
  1000.                        printf("Strings do not compare\n");
  1001. #ifdef DEBUG
  1002. //                       printf("Data sent: \n%s\n",DataPtr);
  1003. //                       printf("Data recv'd: \n%s\n",buffer);
  1004. #endif
  1005.  
  1006.                    }
  1007.  
  1008.  
  1009.                } // IF (fVerify)
  1010.  
  1011.                BytesTransferred += r;
  1012.                DataStartPtr += r;
  1013.  
  1014.                if(DataStartPtr == DataEndPtr)
  1015.                    break;
  1016.  
  1017.            } // IF send() PASSED
  1018.  
  1019.        }while(TRUE);
  1020.  
  1021.        if(fRet == FALSE)
  1022.            break;
  1023.  
  1024.    } // FOR
  1025.  
  1026.    GetLocalTime(&SystemEndTime);
  1027.  
  1028. #ifdef DEBUG
  1029.    printf("End Time:%d:%2d:%2d:%2d\t", SystemEndTime.wHour,
  1030.                                        SystemEndTime.wMinute,
  1031.                                        SystemEndTime.wSecond,
  1032.                                        SystemEndTime.wMilliseconds);
  1033. #endif
  1034.  
  1035.    //
  1036.    // calculate the difference
  1037.    //
  1038.  
  1039.    hourdiff = SystemEndTime.wHour - SystemStartTime.wHour;
  1040.  
  1041.    StartSecond = (SystemStartTime.wHour * 3600) +
  1042.                  (SystemStartTime.wMinute * 60) +
  1043.                  SystemStartTime.wSecond +
  1044.                  (SystemStartTime.wMilliseconds * 0.001);
  1045.  
  1046.    EndSecond = 0;
  1047.  
  1048.    if(SystemEndTime.wMonth != SystemStartTime.wMonth)
  1049.    {
  1050.        EndSecond = (SystemEndTime.wDay * 24) * 3600;
  1051.        switch (SystemStartTime.wMonth)
  1052.        {
  1053.            case 1:
  1054.            case 3:
  1055.            case 5:
  1056.            case 7:
  1057.            case 8:
  1058.            case 10:
  1059.            case 12:
  1060.                    EndSecond = ((31 - SystemStartTime.wDay) * 24) + EndSecond;
  1061.                    break;
  1062.            case 4:
  1063.            case 6:
  1064.            case 9:
  1065.            case 11:
  1066.                    EndSecond = ((30 - SystemStartTime.wDay) * 24) + EndSecond;
  1067.                    break;
  1068.            case 2:
  1069.                    if((SystemStartTime.wYear % 400 == 0) || 
  1070.                       ((SystemStartTime.wYear % 4 == 0) &&
  1071.                        (SystemStartTime.wYear % 100 != 0)))
  1072.                        EndSecond = ((29 - SystemStartTime.wDay) *
  1073.                                      24) + EndSecond;
  1074.                    else
  1075.                        EndSecond = ((28 - SystemStartTime.wDay) *
  1076.                                      24) + EndSecond;
  1077.                    break;
  1078.        }
  1079.    }
  1080.    else
  1081.        if(SystemEndTime.wDay > SystemStartTime.wDay)
  1082.        {
  1083.            EndSecond = ((SystemEndTime.wDay - SystemStartTime.wDay) * 24) * 3600;
  1084.        }
  1085.  
  1086.    EndSecond = EndSecond + (SystemEndTime.wHour * 3600) +
  1087.                (SystemEndTime.wMinute * 60) + SystemEndTime.wSecond +
  1088.                (SystemEndTime.wMilliseconds * 0.001);
  1089.  
  1090.    ElapsedSeconds = EndSecond-StartSecond;
  1091.  
  1092. #ifdef DEBUG
  1093.    printf("Elapsed Time (secs) = %6.3f\n", ElapsedSeconds);
  1094.    printf("Bytes Transferred = %ld\n", BytesTransferred);
  1095.    printf("Send All Done\n");
  1096. #endif
  1097.  
  1098.  
  1099.    if(ElapsedSeconds !=0)
  1100.    {
  1101.        Throughput = (BytesTransferred)/(ElapsedSeconds) ;
  1102.  
  1103. #ifdef DEBUG
  1104.        printf("Throughput (bytes/sec) = %6.2f\n", Throughput);
  1105. #endif
  1106.  
  1107.    }
  1108.  
  1109.    printf("\n");
  1110.  
  1111.    closesocket(clntsock);
  1112.  
  1113.    LocalFree(memhandle);
  1114.    return(TRUE);
  1115.  
  1116. }  
  1117.  
  1118.  
  1119.  
  1120. BOOL CheckForSend(SOCKET s)
  1121. {
  1122.  
  1123.    fd_set writefds;
  1124.    int r;
  1125.  
  1126.  
  1127. #ifdef DEBUG
  1128.    printf("\t\tChecking for Send..\n");
  1129. #endif
  1130.  
  1131.    FD_ZERO(&writefds);
  1132.    FD_SET(s, &writefds);
  1133.  
  1134.    //
  1135.    // indefinite wait select
  1136.    //
  1137.    r =  select(0, NULL, &writefds, NULL, NULL);
  1138.  
  1139.    if( r != 1)
  1140.    {
  1141.        printf("select:error = %d\n", WSAGetLastError());
  1142.        return(FALSE);
  1143.    }
  1144.    return(TRUE);
  1145. }
  1146.   
  1147.   
  1148.   
  1149. BOOL CheckForRecv(SOCKET s)
  1150. {
  1151.  
  1152.    fd_set readfds;
  1153.    int r;
  1154.  
  1155.    FD_ZERO(&readfds);
  1156.    FD_SET(s, &readfds);
  1157.  
  1158. #ifdef DEBUG
  1159.    printf("\t\tChecking for Recv..\n");
  1160. #endif
  1161.  
  1162.    r =  select(0, &readfds, NULL, NULL, NULL);
  1163.  
  1164.    if( r != 1)
  1165.    {
  1166.        printf("select:error = %d\n", WSAGetLastError());
  1167.        return(FALSE);
  1168.    }
  1169.    return(TRUE);
  1170. }
  1171.  
  1172. void usage()
  1173. {
  1174.  
  1175.    printf("prperf -s/c <options>\n");
  1176.    printf("\t-s/c\t Server/Client\n");
  1177.    printf("\t-n\t Server Name\n");
  1178.    printf("\t-t\t Server Type \n");
  1179.    printf("\t-z\t Server Zone \n");
  1180.    printf("\t-p\t Protocol Name (ADSP/PAP)\n");
  1181.    printf("\t-f\t File Name for data to be saved (server only) \n");
  1182.    printf("\t-b\t Number of times to send a 4k buffer (Default = 5) \n");
  1183.    printf("\t-l\t Number of times to re-start prperf (Default = 1) (Client only)\n");
  1184.    printf("\t-v\t Verify Integraty of data transmission. \n");
  1185.    printf("\t-r\t Randomize the size of the base data string. \n");
  1186.    printf("\t-y\t Change ADSP to use SOCK_RDM instead of SOCK_STREAM. \n");
  1187.    printf("\n");
  1188.    exit(1);
  1189.  
  1190. }
  1191.