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