/*---------------------------------------------------------------------+
| Copyright (c) 1995, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| S A S / C S A M P L E |
| |
| NAME: CICCLNT |
| LANGUAGE: C |
| PURPOSE: Demonstrate a CICS TCP Client, that connects to a |
| CICS Listener, CICLISTN, on MVS. The client |
| connects to CICLISTN, then issues a send() and recv(). |
| MVS - |
| COMPILE, LINK, EXECUTE: SUBMIT prefix.SAMPLE.AUX(LC370CLG) |
| where "prefix" is the installation defined high-level- |
| qualifier for the SAS/C product. |
| NOTES: CICCLNT assumes a working TCP/IP environment on both |
| the local and remote hosts, refer to MISC NOTES. |
| TSO - |
| COMPILE: LC370 CLIST |
| LINK: CLK370 CLIST |
| EXECUTE: call 'your.local.load(CICCLNT)' |
| NOTES: CICCLNT assumes a working TCP/IP environment on both |
| the local and remote hosts. Refer to MISC NOTES: |
| CMS - |
| COMPILE: LC370 EXEC |
| LINK: CLINK EXEC |
| EXECUTE: CICCLNT |
| NOTES: CICCLNT assumes a working TCP/IP environment on both |
| the local and remote hosts. Refer to MISC NOTES: |
| MISC NOTES: CICCLNT needs to be customized for the local TCP/IP |
| environment. The local information required by |
| CICCLNT is: |
| HOST_NAME - hostname running CICLISTN. Ensure |
| the TCP/IP environment has been configured |
| for hostname resolution, |
| default is: "mvs" |
| HOST_PORT - port CICLISTN has been configured to do a |
| listen(), default is 3001. |
| HOST_CNT - number of iterations CICCLNT will execute, |
| default is: 20 |
| HOST_SERV - CICS TRANS ID CICLISTN "attaches", |
| default is: CSKS |
| The keywords and values are customized by #define's |
| immediately following the #include statements below: |
+---------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#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 CICLISTN, CSKS TRANS ID, and iterations |
+---------------------------------------------------------------------*/
#define HOST_NAME "mvs" /* Host name running CICLISTN */
#define HOST_PORT 3001 /* CICLISTN "well known port" */
#define HOST_CNT 20 /* Number of iterations for CICCLNT */
#define HOST_SERV "CSKS" /* Name of server TRANS ID */
#define BUF_SIZE 8192 /* Default TCPIP databufferpoolsize */
main()
{
struct hostent *hp; /* gethostbyname() structure */
struct sockaddr_in sa; /* connect() structure */
int count, i, s, msg_len, so_optval;
char *message;
#if defined(OSVS) | defined(CMS)
int si, s_len;
char *h_serv;
int xi;
char *xrecv;
#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 = (unsigned short) HOST_PORT;
/*---------------------------------------------------------------------+
| print CICLISTN and CSKS information for user consumption. |
| |
+---------------------------------------------------------------------*/
printf("\nUsing the following values to connect to CICLISTN\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("TRANS ID is: %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");
s = socket(AF_INET,SOCK_STREAM,0);
if (s == -1)
{
perror("socket call failed");
return -1;
}
else
printf("socket number: %d\n",s);
/*---------------------------------------------------------------------+
| demonstrate how to 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(s, 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(s,&sa,sizeof(sa)) == -1)
{
perror("connect () failed");
return -1;
}
else
printf("connect() successful\n");
/*---------------------------------------------------------------------+
| In an effort to make this application portable, when running on CMS |
| or MVS, convert the HOST_SERV to a network character set. |
+---------------------------------------------------------------------*/
#if defined(OSVS) | defined(CMS)
#define SERV_MAX 4 /* maxsize of server name */
h_serv = (char * ) calloc(SERV_MAX + 1, sizeof(char));
strncpy(h_serv,HOST_SERV,SERV_MAX);
s_len = strlen(HOST_SERV);
for (si=0; si
|