HP OpenVMS Systemsask the wizard |
The Question is: Hi, Question to UCX:(SO_SHARE) can you tell me how to use the SO_SHARE - Flag const int on; setsockopt(socket,SOL_SOCKET,SO_SHARE,&on, sizeof(on)); and which OpenVMS-Versions(AXP,VAX) and UCX-Version support the SO_SHARE - Parameter at the setsockopt-Function The Answer is :
Please contact the Compaq Customer Support Center -- be prepared
to indicate what you are expecting to use the SO_SHARE option for.
Use of the auxillary server, for instance, might be the best
approach to solving your particular problem.
Attached is an example of using the $qio interface to share the
socket between a parent process and a child.
The underlying options have been around for quite some time,
and the particular code below dates back to (at least) the
TCP/IP Services V3.3 release.
/* PARENT.C */
#include <in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <starlet.h>
#include <lib$routines.h>
#include <descrip.h>
#include <dvidef.h>
#include <iodef.h>
#include <clidef.h>
#include <ucx$inetdef.h> /* Provided during UCX installation */
/* Convert short port number from host to network byte order */
#define htons(x) ((unsigned short)((x<<8)|(x>>8)))
int status, reset_timer = FALSE; unsigned long timadr[2], timer_id;
void timer_ast(int x)
if (reset_timer)
{
reset_timer = FALSE;
if (!((status = sys$setimr(0, timadr, timer_ast, timer_id, 0)) & 1))
lib$stop(status);
}
else
{
printf("Server timed out waiting for client connection\n");
exit(1);
}
unsigned long ucx_bg_unit(unsigned short chan)
unsigned long item_code = DVI$_UNIT, unit = 0;
if (!((status = lib$getdvi(&item_code, &chan, 0, &unit)) & 1))
lib$stop(status);
return unit;
short iosb[4];
/* Sub-process termination ast */
ast(int chan)
/* Shut down the connection */
if (!((status = sys$qiow(4, chan, IO$_DEACCESS|IO$M_SHUTDOWN, iosb,
0, 0, 0, 0, 0, UCX$C_DSC_ALL, 0, 0)) & 1))
status = iosb[0];
if (!(status & 1))
{
printf("AST: Failed to close socket on channel\n");;
lib$stop(status);
}
/* Close the connection */
if (!((status = sys$qiow(4, chan, IO$_DEACCESS, iosb,
0, 0, 0, 0, 0, 0, 0, 0)) & 1))
status = iosb[0];
if (!(status & 1))
{
printf("AST: Failed to close socket on channel\n");;
lib$stop(status);
}
/* Deassign the UCX device channel. */
if (!((status = sys$dassgn(chan)) & 1))
printf("AST: Failed to deassign the channel.\n");
main(unsigned int argc, char *argv[])
int r_retlen, one = 1; unsigned long pid, flags;
short channel, channel_1, mbx_chan, sck_parm[2];
char buf[512], bg_device[512]; unsigned char *dummy;
struct SOCKADDRIN local_host, remote_host;
struct IL2 { unsigned short il2_length, parameter_name; char *il2_address;
} lhst_adrs = {sizeof local_host, INET$C_SOCK_NAME, 0};
struct IL3 { unsigned short il3_length, parameter_name; char *il3_address;
unsigned int il3_retlen;
} rhst_adrs = {sizeof remote_host, INET$C_SOCK_NAME, 0, 0};
$DESCRIPTOR(inet_dev, "UCX$DEVICE"); $DESCRIPTOR(mbx_name, "MY_MAILBOX");
$DESCRIPTOR(timbuf, "0 :1:00"); $DESCRIPTOR(command, "run serverc_qio2");
struct { short len, param; int *ptr; }
item_list[] = {
{sizeof(one), UCX$C_SHARE, 0}
},
options = {sizeof(item_list), UCX$C_SOCKOPT, 0};
lhst_adrs. il2_address = (char *) &local_host;
rhst_adrs.il3_address = (char *) &remote_host;
rhst_adrs.il3_retlen = (unsigned int) &r_retlen;
item_list[0].ptr = &one;
options.ptr = (int *) item_list;
sck_parm[0] = UCX$C_TCP; /* TCP/IP protocol */
sck_parm[1] = INET_PROTYP$C_STREAM; /* stream type of socket */
local_host.SIN$W_FAMILY = UCX$C_AF_INET; /* INET family */
local_host.SIN$L_ADDR = UCX$C_INADDR_ANY; /* Any address */
local_host.SIN$W_PORT = htons(atoi(argv[1]));
if (argc != 2)
{
printf("Syntax: server portnumber\n");
exit(-1);
}
/* Create a mailbox for sending BG device name to sub-processes */
if (!((status = sys$crembx (0, &mbx_chan, 0, 0, 0, 0, &mbx_name,
0)) & 1)) lib$stop(status);
/* Assign channel to the UCX device. */
if (!((status = sys$assign(&inet_dev, &channel, 0, 0)) & 1))
{
printf("Failed to assign channel to UCX device\n");;
lib$stop(status);
}
/* Create the socket, set the SHARE option & bind. */
if ((status = sys$qiow(3, channel, IO$_SETMODE, iosb, 0, 0,
&sck_parm, 0, &lhst_adrs, 5, &options, 0)) & 1)
status = iosb[0];
if (!(status & 1))
{
printf("Failed to create and bind socket\n");;
lib$stop(status);
}
/* Set up timer ast - to exit application if server is inactive for
some time
*/
if (!((status = sys$bintim(&timbuf, timadr)) & 1))
lib$stop(status);
if (!((status = sys$setimr(0, timadr, timer_ast, timer_id, 0)) & 1))
lib$stop(status);
/* Accept connections and spawn sub-processes to service clients */
while (1)
{
/* Assign channel for client connection */
if (!((status = sys$assign(&inet_dev, &channel_1, 0, 0)) & 1))
{
printf("Failed to assign channel(_1)\n");;
lib$stop(status);
}
/* Accept a connection from a client. */
if ((status = sys$qiow(3, channel, IO$_ACCESS|IO$M_ACCEPT,
iosb, 0, 0, 0, 0, &rhst_adrs, &channel_1, 0, 0)) & 1)
status = iosb[0];
if (!(status & 1))
{
printf("Failed to accept connection from client\n");;
lib$stop(status);
}
reset_timer = TRUE;
dummy = (unsigned char *) &remote_host.SIN$L_ADDR;
printf("Connection from host: %d.%d.%d.%d, port: %d\n",
dummy[0], dummy[1], dummy[2], dummy[3],
htons(remote_host.SIN$W_PORT));
/* Spawn a sub process to service this client. Set up a sub-process
termination ast and pass connected channel number to this ast */
flags = CLI$M_NOWAIT;
if (!((status = lib$spawn (&command, 0, 0, &flags,
0, &pid, 0, 0, ast, channel_1, 0,
0,
0)) & 1))
lib$stop(status);
printf("Sub-process (pid = %x) is servicing this client\n", pid);
/* Write the BG device name to the mailbox and wait for the spawned
process to read it */
sprintf(bg_device, "BG%d", ucx_bg_unit(channel_1));
if ((status = sys$qiow(0, mbx_chan, IO$_WRITEVBLK, iosb, 0, 0,
bg_device, strlen(bg_device), 0, 0, 0, 0)) & 1)
status = iosb[0];
if (!(status & 1))
{
printf("Parent: Failed to write to mailbox\n");;
lib$stop(status);
}
}
/* Close socket - listener */
if (!((status = sys$qiow(3, channel, IO$_DEACCESS, iosb,
0, 0, 0, 0, 0, 0, 0, 0)) & 1))
status = iosb[0];
if (!(status & 1))
{
printf("Failed to close socket on channel\n");;
lib$stop(status);
}
/* Deassign the UCX device channel. */
if (!((status = sys$dassgn(channel)) & 1))
printf("Failed to deassign the channel.\n");
-------------------------------
/* CHILD.C */
#include <in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <starlet.h>
#include <lib$routines.h>
#include <descrip.h>
#include <iodef.h>
#include <ucx$inetdef.h> /* Provided during UCX installation */
main(unsigned int argc, char *argv[])
register status; short channel, mbx_chan, iosb[4]; char dev[80], buf[80];
$DESCRIPTOR(inet_dev, "UCX$DEVICE"); $DESCRIPTOR(mbx_name, "MY_MAILBOX");
/* Assign a channel to an existing mailbox created by the parent */
if (!((status = sys$crembx (0, &mbx_chan, 0, 0, 0, 0, &mbx_name, 0)) & 1))
lib$stop(status);
/* Read mailbox to get the BG device name */
if ((status = sys$qiow(0, mbx_chan, IO$_READVBLK, iosb, 0, 0,
dev, sizeof(dev), 0, 0, 0, 0)) & 1)
status = iosb[0];
if (!(status & 1))
{
printf("Child: Error reading mailbox\n");
lib$stop(status);
}
inet_dev.dsc$a_pointer = dev;
inet_dev.dsc$w_length = strlen(dev);
/* Assign channel to the UCX device. */
if (!((status = sys$assign(&inet_dev, &channel, 0, 0)) & 1))
{
printf("Failed to assign channel to UCX device\n");;
lib$stop(status);
}
while (1)
{
/* Read I/O buffer. */
memset(buf, 0, sizeof buf);
if ((status = sys$qiow(3, channel, IO$_READVBLK, iosb, 0, 0,
buf, sizeof buf, 0, 0, 0, 0)) & 1)
status = iosb[0];
if (!(status & 1))
{
printf("Failed to read message from client\n");;
lib$stop(status);
}
buf[iosb[1]] = 0;
if (strcmp(buf, "exit") == 0) break;
printf ("%s\n", buf);
/* Send message back to the client */
strcat(buf, " RECEIVED BY SERVER");
if ((status = sys$qiow(3, channel, IO$_WRITEVBLK, iosb, 0, 0,
buf, strlen(buf), 0, 0, 0, 0)) & 1)
status = iosb[0];
if (!(status & 1))
{
printf("Failed to send message to client\n");
lib$stop(status);
}
}
/* Deassign the UCX device channels. */
if (!((status = sys$dassgn(channel)) & 1))
printf("Failed to deassign the channel.\n");
|