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

Windows编程

开发平台:

Visual C++

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