www.sas.com > Service and Support > Technical Support
 
Technical Support SAS - The power to know(tm)
  TS Home | Intro to Services | News and Info | Contact TS | Site Map | FAQ | Feedback


/*---------------------------------------------------------------------+
|                Copyright (c) 1995, SAS Institute Inc.                |
|                  Unpublished - All Rights Reserved                   |
|                      S A S / C   S A M P L E                         |
|                                                                      |
|         NAME: TCPCLNT                                                |
|     LANGUAGE: C                                                      |
|      PURPOSE: Demonstrate a TCP Client application that connects to  |
|               a TCP Listener, TCPLISTN, on MVS. The client           |
|               connects to TCPLISTN, then issues a send() and recv(). |
|   MVS -                                                              |
|      COMPILE, LINK, and EXECUTE: SUBMIT prefix.SAMPLE.AUX(TCPCLNT)   |
|               where "prefix" is the installation defined high-level- |
|               qualifier for the SAS/C product.                       |
|        NOTES: TCPCLNT assumes a working TCP/IP environment on both   |
|               the local and remote hosts, refer to MISC NOTES.       |
|   TSO -                                                              |
|      COMPILE: LC370 CLIST - options ENXREF EXTNAME RENT              |
|         LINK: CLK370 CLIST                                           |
|      EXECUTE: call 'your.load.library(TCPCLNT)'                      |
|        NOTES: TCPCLNT assumes a working TCP/IP environment on both   |
|               the local and remote hosts. Refer to MISC NOTES:       |
|   CMS -                                                              |
|      COMPILE: LC370 EXEC - options ENXREF EXTNAME RENT               |
|         LINK: CLINK EXEC                                             |
|      EXECUTE: TCPCLNT                                                |
|        NOTES: TCPCLNT assumes a working TCP/IP environment on both   |
|               the local and remote hosts. Refer to MISC NOTES:       |
|   MISC NOTES: TCPCLNT needs to be customized for the local TCP/IP    |
|               environment. The local information required by         |
|               TCPCLNT is:                                            |
|               HOST_NAME - hostname running TCPLISTN. Ensure          |
|                           the TCP/IP environment has been configured |
|                           for hostname resolution,                   |
|                           default is: "mvs"                          |
|               HOST_PORT - port TCPLISTN has been configured to do a  |
|                           listen(), default is 13.                   |
|               HOST_CNT  - number of iterations TCPCLNT will execute, |
|                           default is: 2                              |
|               HOST_SERV - module name that TCPLISTN "attaches",      |
|                           default is: TCPTSERV                       |
|               The keywords and values are customized by #define's    |
|               immediately following the #include statements below:   |
+---------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if  __SASC__ == 550
   #include <fcntl.h>
#else
   #include <unistd.h>
#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

/*-------------------------------------------------------------------------+
| Customize the values below to identify the host and port as configured   |
| for the TCPLISTN and TCPTSERV application, iterations and server name.   |
+-------------------------------------------------------------------------*/
#define HOST_NAME  "mvs"       /* Host name running TCPLISTN              */
#define HOST_PORT  13          /* TCPLISTN "well known port"              */
#define HOST_CNT   20          /* Number of iterations for TCPCLNT        */
#define HOST_SERV  "TCPTSERV"  /* Name of server TCPLISTN "attaches"      */
#define SERV_MAX    8          /* Number of bytes for server name         */

#define BUF_SIZE    8192       /* Default TCPIP databufferpoolsize        */

main()
{

struct hostent *hp;            /* gethostbyname() structure               */
struct sockaddr_in sa;         /* connect() structure                     */
int count, i, sockfd, msg_len, s_len, so_optval;
char *message, *h_serv;

#if defined(OSVS) | defined(CMS)  /* variables used for htoncs() and */
   int si, xi;                    /* ntohcs()                        */
#endif

message = (char * ) malloc(BUF_SIZE+1);
memset(message,'\0',sizeof(BUF_SIZE+1));
memset(&sa,'\0',sizeof(sa));  /* initialize "sa"                          */

/*-------------------------------------------------------------------------+
| call gethostbyname() using the HOST_NAME value. If this fails then call  |
| printf() and return.                                                     |
|                                                                          |
+-------------------------------------------------------------------------*/
hp = gethostbyname(HOST_NAME);
if (!hp)
   {
   printf("unable to resolve host name: %s\n",HOST_NAME);
   return (-1);
   }
else
sa.sin_addr.s_addr = *(unsigned long *) hp->h_addr;

/*-------------------------------------------------------------------------+
| assign #define values to application variables                           |
|                                                                          |
+-------------------------------------------------------------------------*/
count = HOST_CNT;
sa.sin_port = htons(HOST_PORT);

/*-------------------------------------------------------------------------+
| print TCPLISTN and TCPTSERV information for user consumption             |
|                                                                          |
+-------------------------------------------------------------------------*/
printf("\nUsing the following values to connect to TCPLISTN\n");
printf("IP address: %s\n",inet_ntoa(sa.sin_addr));
printf("Port number: %d\n",sa.sin_port);
printf("Execution count: %d\n",count);
printf("Server name: %s\n\n",HOST_SERV);

/*-------------------------------------------------------------------------+
| Do the work:  issue a socket(), connect(), send() and recv(). If any     |
| socket call fails, then perror() and return.                             |
+-------------------------------------------------------------------------*/

for (i=1; i <=count; i++)
   {

   printf("iteration number: %d\n", i);
   sa.sin_family = AF_INET;
   printf("socket called()\n");
   sockfd = socket(AF_INET,SOCK_STREAM,0);
   if (sockfd == -1)
      {
      perror("socket call failed");
      return -1;
      }
   else
      printf("socket number: %d\n",sockfd);

/*-------------------------------------------------------------------------+
| demonstrate how one may set a specific socket option with setsockopt().  |
| SO_KEEPALIVE - informs TCP to periodically pool the remote host and      |
| terminate the connection, if a condition exists where: the connection is |
| no longer active and has NOT gone through close() processing.            |
+-------------------------------------------------------------------------*/
   so_optval = 1;
   if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &so_optval,
               sizeof(SO_KEEPALIVE)) == -1)
      perror("setsockopt() so_keepalive failed");
   else
      printf("setsockopt() so_keepalive successful\n");

   if (connect(sockfd,&sa,sizeof(sa)) == -1)
      {
      perror("connect () failed");
      return -1;
      }
   else
      printf("connect() successful\n");

   h_serv =  (char * ) calloc(SERV_MAX + 1, sizeof(char));
   strncpy(h_serv,HOST_SERV,SERV_MAX);
   s_len = strlen(h_serv);
/*-------------------------------------------------------------------------+
| When running on MVS or CMS convert HOST_SERV from a host character set   |
| to a network character set, EBCDIC to ASCII                              |
+-------------------------------------------------------------------------*/
   #if defined(OSVS) | defined(CMS)

      for ( si = 0; si < s_len; si++ )
          h_serv[si] = htoncs(h_serv[si]);
   #endif
/*------------------------------------------------------------------------+
| Call send() with the socket, HOST_SERV value, length, and flags         |
+------------------------------------------------------------------------*/
      msg_len = send(sockfd,h_serv,s_len +1 ,0);

   if (msg_len <0)
      {
      perror("send() failed");
      close(sockfd);
      return -1;
      }
   printf("send() successful\n");

   msg_len = recv(sockfd,message,BUF_SIZE,0);
   if (msg_len <0)
      {
      perror("recv() failed");
      close(sockfd);
      return -1;
      }
   else
      {
/*-------------------------------------------------------------------------+
| When running on MVS or CMS convert the message received from a network   |
| character set to a host character set, ASCII to EBCDIC.                  |
+-------------------------------------------------------------------------*/

      #if defined(OSVS) | defined(CMS)

         for ( xi = 0; xi < msg_len; xi++)
             message[xi] = ntohcs(message[xi]);
      #endif

      printf("recv() successful\n");
      printf("length of data received: %d\n",msg_len);
      printf("data received: %s\n\n",message);
      }

/*-------------------------------------------------------------------------+
| issue a close() after each socket connection is complete. A mis-behaved  |
| application could leave the socket open and let the OS clean-up the      |
| socket, at environment termination. Keeping the socket open may cause    |
| buffer or storage "anomalies".                                           |
+-------------------------------------------------------------------------*/
   close(sockfd);
   }  /* end of for() loop */

printf("TCPCLNT complete\n");
return(0);
}


Copyright (c) 2000 SAS Institute Inc. All Rights Reserved.
Terms of Use & Legal Information | Privacy Statement