/*---------------------------------------------------------------------+ | Copyright (c) 1995, SAS Institute Inc. | | Unpublished - All Rights Reserved | | S A S / C S A M P L E | | | | NAME: TCPTSERV | | LANGUAGE: C | | PURPOSE: Demonstrate a TCP Server, attached by TCPLISTN. The | | "sub-task" will issue a takesocket(), and write to the | | remote client application. | | MVS - | | COMPILE, LINK: SUBMIT prefix.SAMPLE.AUX(TCPTSERV) | | where "prefix" is the installation defined high-level- | | qualifier for the SAS/C product. | | EXECUTE: N/A - TCPTSERV is "attached" by TCPLISTN | | NOTES: TCPTSERV 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: N/A - TCPTSERV is "attached" by TCPLISTN | | NOTES: TCPTSERV 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: TCPTSERV | | NOTES: TCPTSERV assumes a working TCP/IP environment on both | | the local and remote hosts. Refer to MISC NOTES: | | NOTES: TCPTSERV may be executed stand-alone. In this | | environment, customize TIMEPORT. A client application | | using TCPTSERV in this instance will only need to do a | | socket(), connect(), recv() and close(). The TCPCLNT | | may be modified to test TCPTSERV independently. | | MISC NOTES: Use TCPCLNT to test TCPLISTN and TCPTSERV | | MISC NOTES: TCPTSERV uses the following environment variables: | | TCP_SOCK - Socket descriptor passed to TCPTSERV | | TCP_DOMAIN - AF_INET = 2, passed to TCPTSERV | | TCP_NAME - Listener Jobname, passed to TCPTSERV | | TCP_SUBTASKNAME - taskname from getclientid() passed | | to TCPTSERV. | +---------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #if __SASC__ == 550 #include #else #include #endif int GetSocket(int *cs); #define TIMEPORT 0 /* default listen() port if NOT attached */ #define TCP_SOCK_FAILED -1 /* generic return for failed request */ main(int argc, void **argv) { int cs=0; int i; /* Variables used to obtain the time. */ char *p; int len; time_t t; /* Loop count */ int n_times; /* Buffer for outgoing time string. */ char outbuf[128]; /* If there were any arguments passed, echo them */ if (argc >1) { for (i=0; i, Socket# <%d> Name = <%.8s>, Task = <%.8s>\n", clientid.domain, s, clientid.name, clientid.subtaskname); /* Take the passed client socket; takesocket will return a local */ /* socket number enabling us to write to the client */ *cs = takesocket(&clientid, s); /* Check takesocket rc */ if (*cs == -1) { perror("takesock() call failed"); rc = TCP_SOCK_FAILED; } } else { /* * Since this instance is standalone (not invoked by LISTENER, * get a stream socket to communicate. */ s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("timesvr - socket() failed"); return (TCP_SOCK_FAILED); } /* Prepare a socket address for the server. */ memset(&sa_serv,'\0',sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = TIMEPORT; /* Bind our socket to the desired address. Now clients*/ /* specifying this address will reach this server. */ if (bind(s, &sa_serv, sizeof(sa_serv)) == -1) { perror("timesrv - bind() failed"); return (TCP_SOCK_FAILED); } /* Find out what port was choosen and report it. */ sa_len = sizeof(sa_serv); if (getsockname(s, &sa_serv, &sa_len) == -1) { perror("timesrv - getsockname() failed"); return (TCP_SOCK_FAILED); } printf("TIMESRV server port is: %d\n", (int) ntohs(sa_serv.sin_port)); /* Set up a queue for incoming connection requests. */ listen(s, SOMAXCONN); /* Accept a new request. Ask for client's address */ /* so that we can print it if there is an error. */ sa_len = sizeof(sa_clnt); *cs = accept(s, &sa_clnt, &sa_len); if (*cs==-1) { perror("timesrv - accept() failed"); return (TCP_SOCK_FAILED); } } return(rc); }