home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / tcpiptk / hps / echoc.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  15KB  |  400 lines

  1. /********************************************************copyrite.xic********/
  2. /*                                                                          */
  3. /*   Licensed Materials - Property of IBM                                   */
  4. /*   IBM TCP/IP for OS/2                                                    */
  5. /*   (C) Copyright IBM Corporation. 1990,1996.                              */
  6. /*                                                                          */
  7. /*   All rights reserved.                                                   */
  8. /*                                                                          */
  9. /*   US Government Users Restricted Rights -                                */
  10. /*   Use, duplication or disclosure restricted by GSA ADP Schedule          */
  11. /*   Contract with IBM Corp.                                                */
  12. /*                                                                          */
  13. /*--------------------------------------------------------------------------*/
  14. /*  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is             */
  15. /*  sample code created by IBM Corporation. This sample code is not         */
  16. /*  part of any standard or IBM product and is provided to you solely       */
  17. /*  for  the purpose of assisting you in the development of your            */
  18. /*  applications.  The code is provided "AS IS", without                    */
  19. /*  warranty of any kind.  IBM shall not be liable for any damages          */
  20. /*  arising out of your use of the sample code, even if they have been      */
  21. /*  advised of the possibility of such damages.                             */
  22. /*--------------------------------------------------------------------------*/
  23. /******************************HPS CLIENT*************************************/
  24. /*                                                                           */
  25. /*                                                                           */
  26. /*- BUFCNT : Number of 60KByte HPS chunks that you want from the kernel.     */
  27. /*           Defined in cliserv.h. (Note that there is a MAX limit of 64)    */
  28. /*- The VerifyData can be turned ON which will clear all the buffers before  */
  29. /*           each send, and will also validate the incoming data for a known */
  30. /*           pattern. This is time intensive but can be done to check the    */
  31. /*           possible buffer overlap.                                        */
  32. /*- The VerifyMem can be used to optionally check to see if after the        */
  33. /*           semaphore wait if the kernel mem ptrs are really released.      */
  34. /*           None of the ptrs should be NULL at this time. This checking     */
  35. /*           is not a must but can be optionally turned On for ensuring the  */
  36. /*           functionality.                                                  */
  37. /*- Use the -s switch is you explicitly wonna use the semaphores             */
  38. /*- If compiled with DEBUG it will display all the kernel ptrs.              */
  39. /*- I am following a stupid way of waiting for the release of EACH and EVERY */
  40. /*  buffer before proceeding further, just in order to save complex coding in*/
  41. /*  QUERY_MEMMAPIO. This can be written much better for optimised performance*/
  42. /*  But for this test excercise performance is not considered an issue . amol*/
  43. /*****************************************************************************/
  44. #define INCL_DOSSEMAPHORES
  45. #define INCL_DOSERRORS
  46.  
  47. #include "cliserv.h"
  48.  
  49. int read_stream(int fd, char *ptr, int maxbytes);
  50.  
  51. int main(int argc, char *argv[]) {
  52.    struct sockaddr_in   serv;
  53.    u_short port = TCP_SERV_PORT;
  54.    int i, j, k, sockfd, n, cnt, nread, nsent, NumOfBufs,
  55.         VerifyData=0, VerifyMem=0, UseSems=0, wprinted=0;
  56.    int send_data = 0,recv_data = 0;                            /* aarti */
  57.    int mib[4];
  58.    unsigned int needed;
  59.    APIRET rc;
  60.    ULONG dontcare;
  61.    int len = NUMHPSBLOCKS * HPSBLOCKSIZE * BUFCNT;
  62.    int num = ITERATIONS;
  63.    HEV arrayofsem[NUMHPSBLOCKS*BUFCNT];
  64.    long arrayofptrs[NUMHPSBLOCKS*BUFCNT];
  65.    struct msghdr msg;
  66.    struct iovec iov[NUMHPSBLOCKS*BUFCNT];
  67.    char *name;
  68.    HMUX hmux;
  69.    SEMRECORD semrec[NUMHPSBLOCKS*BUFCNT];
  70.    char *cp;
  71.  
  72.    if (argc < 2) {
  73.       printf("Usage: echoc -p#### -n####  -m -s -d server_name\n");
  74.       printf("       p=port, n=number_of_iterations, m=Mem Verification, d=Data validation, s=Use Semaphores\n");
  75.       return(0);
  76.    }
  77.  
  78.    for (n = 1; n < argc; n++) {
  79.       if (argv[n][0] == '-') {
  80.          if (argv[n][1] == 'p') {
  81.             port = atoi(&argv[n][2]);
  82.          } else if(argv[n][1] == 'n') {
  83.             num = atoi(&argv[n][2]);
  84.          } else if(argv[n][1] == 'm') {
  85.             VerifyMem=TRUE;
  86.          } else if(argv[n][1] == 'd') {
  87.             VerifyData=TRUE;
  88.          } else if(argv[n][1] == 's') {
  89.             UseSems=TRUE;
  90.          } else {
  91.             printf("Usage: echoc -p#### -n####  -m -s -d  server_name\n");
  92.             printf("       p=port, n=number_of_iterations, m=Mem Verification, d=Data validation, s=Use Semaphores\n");
  93.             return(0);
  94.          }
  95.       } else {
  96.          name = argv[n];
  97.       }
  98.    }
  99.  
  100.    printf("HPS Client :(%s)port=%d, Iterations=%d\n", argv[0], port, num);
  101.  
  102.    cp = malloc(len);
  103.    if (!cp) {
  104.      printf("malloc failed for %d bytes\n",len);
  105.      exit(1);
  106.    }
  107.  
  108.    if (UseSems) {
  109.       printf("   HPS Client Using Semaphores\n");
  110.  
  111.       /* Try to get the semaphore handles, and initialize the array of ptrs */
  112.       for (i = 0; i < NUMHPSBLOCKS*BUFCNT ; i++) {
  113.         rc = DosCreateEventSem(NULL, &arrayofsem[i], DC_SEM_SHARED, FALSE);
  114.         if (rc != NO_ERROR) {
  115.            printf("DosCreateEventSem=%d\n", rc);
  116.            exit(1);
  117.         }
  118.         arrayofptrs[i]    = arrayofsem[i];
  119.         semrec[i].hsemCur = (HSEM)arrayofsem[i];
  120.         semrec[i].ulUser  = i;
  121.       }
  122.  
  123.       /* create the hmux sempahore */
  124.       rc = DosCreateMuxWaitSem(NULL, &hmux, NUMHPSBLOCKS*BUFCNT, semrec, DCMW_WAIT_ALL);
  125.       if (rc != NO_ERROR) {
  126.          printf("DosCreateMuxWaitSem=%d\n", rc);
  127.          exit(1);
  128.       }
  129.    } /* UseSems */
  130.    else {
  131.      for (i = 0; i < NUMHPSBLOCKS*BUFCNT ; i++)
  132.        arrayofptrs[i] = 0;
  133.      printf("   HPS Client Without Semaphores\n");
  134.    }
  135.  
  136.    for (NumOfBufs=0; NumOfBufs < BUFCNT; NumOfBufs++) {
  137.      mib[0] = CTL_OS2;
  138.      mib[1] = AF_INET;
  139.      mib[2] = 0;
  140.      mib[3] = OS2_MEMMAPIO;
  141.      needed = 15*4;    // 60K
  142.  
  143.      /* buffers return in old, to be free in new */
  144.      if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), (arrayofptrs+(15*NumOfBufs)), &needed, NULL, 0) < 0) {
  145.         printf("sysctl(MEMMAPIO)=%d, errno=%d\n", rc, sock_errno());
  146.         exit(1);
  147.      }
  148.    } /* for */
  149.  
  150.  
  151.    if (VerifyMem) {
  152.     for (NumOfBufs=0; NumOfBufs < BUFCNT; NumOfBufs++) {
  153.        /* check to make sure that we have not got a NULL ptr from stack */
  154.        mib[0] = CTL_OS2;
  155.        mib[1] = AF_INET;
  156.        mib[2] = 0;
  157.        mib[3] = OS2_QUERY_MEMMAPIO;
  158.        needed = 15*4;   // 60K
  159.  
  160.        if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), (arrayofptrs+(15*NumOfBufs)), &needed, NULL, 0) < 0) {
  161.          printf("sysctl(MEMMAPIO)=%d, errno=%d\n", rc, sock_errno());
  162.          exit(1);
  163.        }
  164.     } /* for */
  165.  
  166.     for (i = 0; i < NUMHPSBLOCKS*BUFCNT; i++) {
  167. #ifdef DEBUG
  168.       printf("HPS memory ptr %d:\t%p\n", i, arrayofptrs[i]);
  169. #endif
  170.       if (arrayofptrs[i] == 0) {
  171.          printf("Opsss. Memory allocated  by stack has a NULL ptr !\n");
  172.          exit(1);
  173.       }
  174.     }
  175.    } /* VerfiyMem */
  176.  
  177.    sockfd = socket(PF_INET, SOCK_STREAM, 0);
  178.    if (sockfd < 0) {
  179.       printf("socket=%d (%d)\n", sockfd, sock_errno());
  180.       exit(1);
  181.    }
  182.  
  183.    memset(&serv, 0, sizeof(serv));
  184.    serv.sin_family = AF_INET;
  185.    serv.sin_addr.s_addr = inet_addr(name);
  186.    if (serv.sin_addr.s_addr == -1) {
  187.       struct hostent *hp;
  188.  
  189.       hp = gethostbyname(name);
  190.       if (hp == NULL) {
  191.          printf("Gethostbyname(%s) failed\n", name);
  192.          exit(1);
  193.       }
  194.       serv.sin_addr.s_addr = *(u_long *)hp->h_addr;
  195.    }
  196.    serv.sin_port = htons(port);
  197.  
  198.    i = connect(sockfd, (struct sockaddr *) &serv, sizeof(serv));
  199.    if (i < 0) {
  200.       printf("connect=%d (%d)", rc, sock_errno());
  201.       exit(1);
  202.    }
  203.  
  204.    cnt = len / HPSBLOCKSIZE;
  205.  
  206.    msg.msg_name = NULL;
  207.    msg.msg_namelen = 0;
  208.    msg.msg_iov = iov;
  209.    msg.msg_iovlen = cnt;
  210.    n = len;
  211.    for (i = 0; i < cnt; i++) {
  212.       iov[i].iov_base = (void *)arrayofptrs[i];
  213.       if (n < HPSBLOCKSIZE) {
  214.          iov[i].iov_len = n;
  215.          n = 0;
  216.          break;
  217.       } else {
  218.          iov[i].iov_len = HPSBLOCKSIZE;
  219.          n -= HPSBLOCKSIZE;
  220.       }
  221.    }
  222.  
  223.    for (i = 0; i < num; i++) {
  224.  
  225.  
  226.       /* Fill in some data */
  227.       for (k = 0; k < (NUMHPSBLOCKS*BUFCNT); k++)
  228.          memset((void *)arrayofptrs[k], CLI_CHAR+k+send_data, HPSBLOCKSIZE);
  229.  
  230.       nsent = sendmsg(sockfd, &msg, MSG_MAPIO);
  231.  
  232.       if (nsent != len) {
  233.          printf("sendmsg=%d (%d) len=%d\n", nsent, sock_errno(), len);
  234.          exit(1);
  235.       } else
  236.          printf("HPS Client : sent %d bytes to \t %s \n", nsent, inet_ntoa(serv.sin_addr));
  237.  
  238.       if (send_data == 9)           /* aarti */
  239.          send_data = 0;
  240.       else
  241.          send_data++;
  242.  
  243.       nread = read_stream(sockfd, cp, len);
  244.       if (nread < 0) {
  245.          printf("read error=%d (%d)", nread, sock_errno());
  246.          exit(1);
  247.       }else
  248.          printf("HPS Client : read %d bytes from \t %s \n", nread, inet_ntoa(serv.sin_addr));
  249.  
  250.       if (nread == 0) /* closed connection */
  251.          break;
  252.  
  253.       if (VerifyData) {
  254.         for (j=0; j< (NUMHPSBLOCKS*BUFCNT); j++)
  255.           for (k=0; k< HPSBLOCKSIZE; k++)
  256.             if (cp[j*HPSBLOCKSIZE+k] != SERV_CHAR + j + recv_data)
  257.             {
  258.                  printf("*** ERROR Found in received data. Got %x Expected (%x) at BlockNumber:%d, Iteration:%d, Index in 4K block:%d\n",cp[j*HPSBLOCKSIZE+k], SERV_CHAR+j+i,j,i,k);
  259.                  exit(1);
  260.             }
  261.         printf("Data verification done\n ");
  262.         /* Clear the cp array */
  263.         memset((void *)(cp),0, HPSBLOCKSIZE * NUMHPSBLOCKS * BUFCNT);
  264.  
  265.         if (recv_data == 9)                        /* aarti */
  266.             recv_data = 0;
  267.         else
  268.             recv_data++;
  269.  
  270.       } /* VerifyData */
  271.  
  272.  
  273.        /*  WAIT till the buffers are released by HP Send */
  274.       wprinted=0;
  275. wait:
  276.       if (UseSems) {
  277.         printf("Waiting on the Mutex Sem \n");
  278.         rc = DosWaitMuxWaitSem(hmux, SEM_INDEFINITE_WAIT, &dontcare);
  279.         if (rc != NO_ERROR) {
  280.            printf("DosWaitMuxWaitSem=%d\n", rc);
  281.            exit(1);
  282.         }
  283.  
  284.         /* AGAIN create the hmux sempahore */
  285.         rc = DosCreateMuxWaitSem(NULL, &hmux, (NUMHPSBLOCKS*BUFCNT), semrec, DCMW_WAIT_ALL);
  286.         if (rc != NO_ERROR) {
  287.            printf("DosCreateMuxWaitSem=%d\n", rc);
  288.            exit(1);
  289.         }
  290.       } /* if Using Semaphores */
  291.       else
  292.       {
  293.          /* Using the simplest way of waiting for the release of EACH and EVERY    */
  294.          /* buffer before proceeding further, just in order to save complex coding */
  295.  
  296.          /* As the sysctl query_memmapio modifies the passed in array, save a copy */
  297.          int CopyCnt;
  298.          long arrayofptrsSave[NUMHPSBLOCKS*BUFCNT];
  299.  
  300.          for (CopyCnt=0;CopyCnt < (sizeof(arrayofptrs)/sizeof(arrayofptrs[0]));CopyCnt++) {
  301.             arrayofptrsSave[CopyCnt] = arrayofptrs[CopyCnt];
  302.          }
  303.  
  304.          /* Verify that the memory buffers are indeed released by now */
  305.          mib[0] = CTL_OS2;
  306.          mib[1] = AF_INET;
  307.          mib[2] = 0;
  308.          mib[3] = OS2_QUERY_MEMMAPIO;
  309.          needed = 15*4*BUFCNT;
  310.  
  311.          if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), arrayofptrsSave, &needed, NULL, 0) < 0) {
  312.             printf("sysctl(MEMMAPIO)=%d, errno=%d\n", rc, sock_errno());
  313.             exit(1);
  314.          }
  315.          for (j=0; j< NUMHPSBLOCKS*BUFCNT; j++) {
  316.            if ( !(arrayofptrsSave[j]) ) {
  317.              if (!wprinted) {
  318.                printf("Waiting for kernel to release each and every buffer :");
  319.                wprinted++;
  320.              }
  321.              printf("-");
  322.              goto wait;
  323.            }
  324.          }
  325.          if(wprinted)
  326.            printf("Buffer Released\n");
  327.       } /* if NOT Using Semaphores */
  328.  
  329.       /* AGAIN Refill the iov_base with the arrayofptrs */
  330.       n = len;
  331.       for (j = 0; j < cnt; j++) {
  332.          iov[j].iov_base = (void *)arrayofptrs[j];
  333.          if (n < HPSBLOCKSIZE) {
  334.             iov[j].iov_len = n;
  335.             n = 0;
  336.             break;
  337.          } else {
  338.             iov[j].iov_len = HPSBLOCKSIZE;
  339.             n -= HPSBLOCKSIZE;
  340.          }
  341.       }
  342.  
  343.     if (VerifyMem) {
  344.          int CopyCnt;
  345.          long arrayofptrsSave[NUMHPSBLOCKS*BUFCNT];
  346.  
  347.          for (CopyCnt=0;CopyCnt < (sizeof(arrayofptrs)/sizeof(arrayofptrs[0]));CopyCnt++) {
  348.             arrayofptrsSave[CopyCnt] = arrayofptrs[CopyCnt];
  349.          }
  350.  
  351.          mib[0] = CTL_OS2;
  352.          mib[1] = AF_INET;
  353.          mib[2] = 0;
  354.          mib[3] = OS2_QUERY_MEMMAPIO;
  355.          needed = 15*4*BUFCNT;
  356.  
  357.          if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), arrayofptrsSave, &needed, NULL, 0) < 0) {
  358.             printf("sysctl(MEMMAPIO)=%d, errno=%d\n", rc, sock_errno());
  359.             exit(1);
  360.          }
  361.  
  362.          for (j = 0; j < (NUMHPSBLOCKS*BUFCNT); j++) {
  363. #ifdef DEBUG
  364.             printf("HPS Memory ptr %d:\t%p %p\n", j, arrayofptrs[j], arrayofptrsSave[j]);
  365. #endif
  366.             if ( !arrayofptrsSave[j]) {
  367.               printf("Opsss. Memory not yet freed by stack !!! %d:%p\n",j,arrayofptrs[j]);
  368.               exit(1);
  369.             }
  370.          }
  371.       }  /* VerifyMem */
  372.  
  373.    } /* for Iterations */
  374.  
  375.    printf("HPS Client successfully completed %d iterations\n\n",i);
  376.  
  377.    /* system will close all semaphores and sockets and memmapped */
  378.    return 0;
  379. }
  380.  
  381.  
  382. int read_stream(int fd, char *ptr, int maxbytes) {
  383.    int nleft, nread;
  384.  
  385.    printf("Receiving %d bytes\n", maxbytes);
  386.    nleft = maxbytes;
  387.    while (nleft > 0) {
  388.       nread = recv(fd, ptr, nleft, 0);
  389.       if (nread < 0)
  390.          return(nread);          /* error, return < 0 */
  391.       else if (nread == 0)
  392.          break;                          /* EOF, return #bytes read */
  393.       nleft -= nread;
  394.       ptr += nread;
  395.       printf(".");
  396.    }
  397.    printf("\n");
  398.    return(maxbytes - nleft);               /* return >= 0 */
  399. }
  400.