/*====================================================================
*
* COPYRIGHT (C) 1989, 1998 BY
* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
*
* This software is furnished under a license and may be used and copied
* only in accordance with the terms of such license and with the
* inclusion of the above copyright notice. This software or any other
* copies thereof may not be provided or otherwise made available to any
* other person. No title to and ownership of the software is hereby
* transferred.
*
* The information in this software is subject to change without notice
* and should not be construed as a commitment by DIGITAL EQUIPMENT
* CORPORATION.
*
* DIGITAL assumes no responsibility for the use or reliability of its
* software on equipment which is not supplied by DIGITAL.
*
*
*
* FACILITY:
* INSTALL
*
*
* ABSTRACT:
* This is an example of a TCP/IP client using the QIO
* interface.
*
* ENVIRONMENT:
* TCPIP V5.0 or higher
*
* BUILD INSTRUCTIONS:
*
* To link in VAXC/VMS you must have the following
* entries in your .opt file:
* sys$library:tcpip$ipc.olb/lib
* sys$share:vaxcrtl.exe/share
*
* For DEC C or DEC C++, compile /PREFIX=ALL and link via
* $ link TCPIP$TCP_SERVER_QIO
*
* To build this example program use commands of the form,
*
* using the DEC "C" compiler:
*
* $ cc/prefix=all TCPIP$TCP_SERVER_QIO.C
* $ link TCPIP$TCP_SERVER_QIO
*
* using the DEC "C++" compiler:
*
* $ cxx/prefix=all/define=VMS TCPIP$TCP_SERVER_QIO.C
* $ link TCPIP$TCP_SERVER_QIO
*
* using the VAX "C" compiler:
*
* $ cc /vaxc TCPIP$TCP_SERVER_QIO.C
* $ link TCPIP$TCP_SERVER_QIO, -
* SYS$LIBRARY:TCPIP$IPC/LIB, -
* SYS$INPUT/OPTIONS
* SYS$SHARE:TCPIP$IPC_SHR/SHARE
* SYS$SHARE:VAXCRTL.EXE/SHARE
*
* AUTHORS:
* TCPIP Developer
*
* CREATION DATE: May 23, 1989
*
* MODIFICATION HISTORY:
*
* 16 May 1996 Joseph J. Vlcek
* Make compatible with the DEC C and DEC C++ compilers.
* Add directions on how to build this example modules.
*
* 5 Nov 1997 Immi Mohammed
* Changed ucx$inetdef.h to shrlib$:inet_user.h
*
* 31 Mar 1998 Jason Fountain
* Initialize retval
* Changed shrlib$:inet_user.h to tcpip$inetdef.h
*/
#include <descrip.h> /* VMS descriptor stuff */
#include <errno.h> /* Unix style error codes for IO routines. */
#include <in.h> /* internet system Constants and structures. */
#include <inet.h> /* Network address info. */
#include <iodef.h> /* I/O FUNCTION CODE DEFS */
#include <lib$routines.h> /* LIB$ RTL-routine signatures. */
#include <lib$routines.h> /* LIB$ RTL-routine signatures.*/
#include <netdb.h> /* Network database library info. */
#include <signal.h> /* UNIX style Signal Value Definitions */
#include <socket.h> /* TCP/IP socket definitions. */
#include <ssdef.h> /* SS$_<xyz> sys ser return stati <8-) */
#include <starlet.h> /* Sys ser calls */
#include <stdio.h> /* UNIX 'Standard I/O' Definitions */
#include <stdlib.h> /* General Utilities */
#include <string.h> /* String handling function definitions */
#include <tcpip$inetdef.h> /* TCPIP network definitions */
/* Convert short port number from host to network byte order */
#define htons(x) ((unsigned short)((x<<8)|(x>>8)))
main() {
int status; /* For return status */
short channel; /* INET channel */
short channel_1; /* Template for ACCEPT */
short sck_parm[2]; /* Socket creation parameter */
short iosb[4]; /* I/O status block */
char buf[512];
int buflen = 512; /* buffer length */
int retval = 0;
short port;
unsigned char *dummy;
unsigned int r_retlen;
int one=1;
struct sockaddr_in local_host, remote_host;
struct IL2 {
unsigned int il2_length;
char *il2_address;
} lhst_adrs;
struct IL3 {
unsigned int il3_length;
char *il3_address;
unsigned int* il3_retlen;
} rhst_adrs;
//--------------------
// struct dsc$descriptor inet_dev =
// {10, DSC$K_CLASS_S, DSC$K_DTYPE_T, "TCPIP$DEVICE"}; /* original (broken) code */
//--------------------
// struct dsc$descriptor inet_dev =
// {12, DSC$K_CLASS_S, DSC$K_DTYPE_T, "TCPIP$DEVICE"}; /* fixed code */
//--------------------
$DESCRIPTOR( inet_dev, "TCPIP$DEVICE:" ); /* better fixed code */
//--------------------
struct { short len, param; int *ptr; }
item_list[] = {{sizeof(one), TCPIP$C_REUSEADDR, (int*)0 }},
options = {sizeof(item_list), TCPIP$C_SOCKOPT, (int*)0 };
item_list[0].ptr = &one;
options.ptr = (int*)item_list;
lhst_adrs.il2_length = sizeof local_host;
lhst_adrs.il2_address = (char *)&local_host;
rhst_adrs.il3_length = sizeof remote_host;
rhst_adrs.il3_address = (char*)&remote_host;
rhst_adrs.il3_retlen = &r_retlen;
sck_parm[0] = TCPIP$C_TCP; /* TCP/IP protocol */
sck_parm[1] = INET_PROTYP$C_STREAM; /* stream type of socket */
local_host.sin_family = TCPIP$C_AF_INET; /* INET family */
local_host.sin_addr.s_addr = TCPIP$C_INADDR_ANY; /* Any address */
while (retval != 1) {
printf("Enter local port number:\n");
retval = scanf("%hd", &port);
if (retval == 1)
local_host.sin_port = htons(port);
else scanf("%s",buf); /* discard bad input */
}
/* Assign two channels to the TCPIP device. */
status = sys$assign(&inet_dev, &channel, 0, 0);
if (status & 1)
status = sys$assign(&inet_dev, &channel_1, 0, 0);
if (!(status & 1)) {
printf("Failed to assign channel to TCPIP device.\n");
exit(status);
}
/* Create the socket and set the REUSEADDR option. */
status = sys$qiow(3, /* Event flag */
channel, /* Channel number */
IO$_SETMODE, /* I/O function */
iosb, /* I/O status block */
0, 0,
&sck_parm, 0, /* P1 Socket creation parameter */
0, 0,
&options, 0); /* P5 Socket option descriptor */
if (status & 1) status = iosb[0];
if (!(status & 1)) {
printf("Failed to create the device socket.\n");
exit(status);
}
/* Bind to chosen port number (after REUSEADDR is set above). */
status = sys$qiow(3, /* Event flag */
channel, /* Channel number */
IO$_SETMODE, /* I/O function */
iosb, /* I/O status block */
0, 0,
0, 0,
&lhst_adrs, /* P3 local socket name */
3, /* P4 Connection backlog */
0, 0);
if (status & 1) status = iosb[0];
if (!(status & 1)) {
printf("Failed to bind the device socket.\n");
exit(status);
}
printf("%d\n", channel);
printf("%d\n", channel_1);
printf("%d\n", sck_parm[0]);
printf("%d\n", sck_parm[1]);
printf("%d\n", lhst_adrs.il2_length);
printf("%d\n", lhst_adrs.il2_address);
printf("%d\n", rhst_adrs.il3_length);
printf("%d\n", rhst_adrs.il3_address);
printf("%d\n", rhst_adrs.il3_retlen);
/* Accept a connection from a client. */
status = sys$qiow(3, /* Event flag */
channel, /* Channel number */
IO$_ACCESS|IO$M_ACCEPT, /* I/O function */
iosb, /* I/O status block */
0, 0,
0, 0,
&rhst_adrs, /* P3 Remote IP address*/
&channel_1, /* P4 Channel for new socket */
0, 0);
if (status & 1) status = iosb[0];
if (!(status & 1)) {
printf("Failed to accept a connection from a client.\n");
exit(status);
}
dummy = (unsigned char *)&remote_host.sin_addr;
printf("Connection from host: %d.%d.%d.%d, port: %d\n",
dummy[0], dummy[1], dummy[2], dummy[3],
htons(remote_host.sin_port));
/* Read I/O buffer. */
status = sys$qiow(3, /* Event flag */
channel_1, /* Channel number */
IO$_READVBLK, /* I/O function */
iosb, /* I/O status block */
0, 0,
buf, /* P1 buffer */
buflen, /* P2 buffer length */
0, 0, 0, 0);
if (status & 1) status = iosb[0];
if (!(status & 1))
printf("Failed to read from socket.\n");
/* If all is well, print message */
printf ("Received text: %s\n", buf);
/* Shut down the socket (optional). */
status = sys$qiow(3,
channel_1,
IO$_DEACCESS|IO$M_SHUTDOWN,
iosb,
0, 0,
0, 0, 0,
TCPIP$C_DSC_ALL, /* P4 Discard all packets */
0, 0);
if (status & 1) status = iosb[0];
if (!(status & 1))
printf("Failed to shut down the socket.\n");
/* Close the sockets -- accepted and listner (optional). */
status = sys$qiow(3,
channel_1,
IO$_DEACCESS,
iosb,
0, 0,
0, 0, 0, 0, 0, 0);
if (status & 1) status = sys$qiow(3,
channel,
IO$_DEACCESS,
iosb,
0, 0,
0, 0, 0, 0, 0, 0);
if (status & 1) status = iosb[0];
if (!(status & 1))
printf("Failed to close the socket.\n");
/* Deassign the TCPIP device channels. */
status = sys$dassgn(channel_1);
if (status & 1) status = sys$dassgn(channel);
if (!(status & 1))
printf("Failed to deassign the channel.\n");
}
Back to OpenVMS
Back to OpenVMS Demo Index
Back to Home
Neil Rieck
Kitchener - Waterloo - Cambridge, Ontario, Canada.