[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference lassie::ucx

Title:DEC TCP/IP Services for OpenVMS
Notice:Note 2-SSB Kits, 3-FT Kits, 4-Patch Info, 7-QAR System
Moderator:ucxaxp.ucx.lkg.dec.com::TIBBERT
Created:Thu Nov 17 1994
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:5568
Total number of notes:21492

5337.0. "IO$_READVBLK with AST" by BARNA::DSMAIL () Fri Mar 14 1997 07:48

Hello:

My customer has a problem because he wants to get some example using the 
IO$_READVBLK with AST. All the examples that are present in the Systems
Service and C Socket Programming doesn't use the AST (the fields related are 0).

Can anyone help me pointing to some place to get an example.

Thanks in advance,

Crist�bal

Following is a bit of an example extracted from this manual. Note that the
fields following the iosb are 0 (AST fields)

/*
  ** Perform the QIO read operation
  */

        status = SYS$QIOW( 0,            /* Event flag */
                              channel,    /* 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) == 0) {
             printf("Failed to read from inet device \n") ;
             return(status) ;
        }
  /*

    
T.RTitleUserPersonal
Name
DateLines
5337.1its thereUTRTSC::KNOPPERSOswald KnoppersFri Mar 14 1997 08:3620
There is one (UDP) example using this in ucx$examples. Check out the
example UCX$UDP_SERVER_QIO.C. It does (amongst other things):

        /*
         * Perform a QIO read operation with completion AST.
         */
        status = sys$qio( 3,            /* Event flag */
                        channel,        /* Channel number */
                        IO$_READVBLK,   /* I/O function */
                        iosb,           /* I/O status block */
                        read_ast,       /* AST routine address */
                        0,
                        buf,            /* P1 buffer */
                        buflen,         /* P2 buffer length */
                        &rsck_adrs,     /* P3 buffer to get remote hostadrs */
                        0,0,0) ;

Regards,

Oswald
5337.2Need for TCP not for UDP.BARNA::DSMAILTue Mar 18 1997 04:217
    Thanks for your quick answer. I've explained this to the customer but
    he uses TCP not UDP, and  all of examples with TCP put the AST fields
    to 0. Could you get me an example with TCP?.
    The customer was trying already to apply the UDP example to TCP
    protocol without success.
    
    Crist�bal.
5337.3UTRTSC::KNOPPERSOswald KnoppersTue Mar 18 1997 05:258
>    The customer was trying already to apply the UDP example to TCP
>    protocol without success.

Can you elaborate on this?

Regards,

Oswald
5337.4more info form customerBARNA::DSMAILThu Mar 20 1997 12:12278
Hello Oswald:
    
    following is an example that is failing and the explanation of the
    problem that customer has wroten.
    
    Regards,
    Crist�bal
    
*******************************************************************************
/*  Program TCP_QIO.C */
/* =================*/

#include <in.h>
#include <string.h>
#include <starlet.h>
#include <descrip.h>
#include <iodef.h>
#include <ucx$inetdef.h>	/* Provided during UCX installation */

#include <stdio.h>

/* Convert short port number from host to network byte order */
#define htons(x) ((unsigned short)((x<<8)|(x>>8)))

/* Global data */
/* --------------- */
struct	SOCKADDRIN remote_host;

struct	IL2 {
	unsigned int il2_length;
	char *il2_address;
} rhst_adrs = {sizeof remote_host, &remote_host};

short	channel;		/* INET channel */
char	buffer[1];

void connect_ast(void);
void read_ast(void);

main() {
	int	status;					/* For return status */
	short	sck_parm[2];				/* Socket creation parameter */
	short	iosb[4];					/* I/O status block */

	char	buf[512] = "Hi there";
	int	buflen = 512;				/* buffer length */
	int	retval;
	char	junk[256], dot, *dummy;			/* used for scanf */
	short	port;

	struct	dsc$descriptor inet_dev =
		{10, DSC$K_CLASS_S, DSC$K_DTYPE_T, "UCX$DEVICE"};

	sck_parm[0] = UCX$C_TCP;			/* TCP/IP protocol */
	sck_parm[1] = INET_PROTYP$C_STREAM;	/* stream type of socket */

	remote_host.SIN$W_FAMILY = UCX$C_AF_INET;	/* INET family */
	dummy = &remote_host.SIN$L_ADDR;

	while (retval != 7) {
		printf ("Enter remote host Internet address (a.b.c.d):\n");
		retval = scanf("%d %c %d %c %d %c %d", 
			&dummy[0], &dot, &dummy[1], &dot,
			&dummy[2], &dot, &dummy[3]);
		if (retval != 7) 
			scanf("%s",junk);	/* discard bad input */
	} 

	while (retval != 1) {
		printf("Enter remote port number:\n");
		retval = scanf("%hd", &port);
		if (retval == 1)
			remote_host.SIN$W_PORT = htons(port); 
		else scanf("%s",junk);	/* discard bad input */
	}

	/* Assign a channel to the UCX device. */
	status = sys$assign(&inet_dev, &channel, 0, 0);
	if (!(status & 1)) {
		printf("Failed to assign channel to UCX device.\n");
		exit(status);
	}

	/* Create the socket */
	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,
			0, 0);
	if (status & 1) status = iosb[0];
	if (!(status & 1)) {
		printf("Failed to create and bind the device socket.\n");
		exit(status);
	}

	/* Connect to specified host and port number */
	status = sys$qiow(3,			/* Event flag */
			channel,			/* Channel number */
			IO$_ACCESS,		/* I/O function */
			iosb,			/* I/O status block */
			0, 0,
			0, 0,
			&rhst_adrs,		/* P3 Remote IP address */
			0, 0, 0);
	if (status & 1) status = iosb[0];
	if (!(status & 1)) {
		printf("Failed to connect to remote host.\n");
		exit(status);
	}

	/* Read I/O buffer. (AST)*/
       	status = sys$qio(
                    3,                       			/* Efn			*/
                    channel,           			/* Channel I/O		*/
                    IO$_READVBLK | IO$M_NOECHO, 	/* Func			*/
                    iosb,                    			/* Status Channel	*/
                    read_ast,	         			/* Ast routine address	*/
                    0,	       		 		/* Ast param 		*/
                    buffer,     	      			/* Buffer of read	*/
                    1,		    			/* N� Charac. read	*/
                    0,/*&rhst_adrs,*/			/* P3 Remote IP address	*/
/* In parameter P3 used two values (0/&rhst_adrs) */
                    0,                       			/* P4			*/
                    0,                       			/* Prompt		*/
                    0);                      			/* N� Charac. Prompt	*/
	if (status & 1) status = iosb[0];
	if (!(status & 1))
		printf("Failed to read to socket with AST (1).\n");

	/* Read I/O buffer. (AST)*/
       	status = sys$qio(
                    0,                       			/* Efn			*/
                    channel,           			/* Channel I/O		*/
                    IO$_READVBLK | IO$M_NOECHO, 	/* Func			*/
                    iosb,                    			/* Status Channel	*/
                    connect_ast,				/* Ast routine address	*/
                    0,	       		 		/* Ast param 		*/
                    buffer,     	     		 	/* Buffer of read	*/
                    1,		    			/* N� Charac. read	*/
                    0,/*&rhst_adrs,*/			/* P3 Remote IP address	*/
/* In parameter P3 used two values (0/&rhst_adrs) */
                    0,                       			/* P4			*/
                    0,                       			/* Prompt		*/
                    0);                      			/* N� Charac. Prompt	*/
	if (status & 1) status = iosb[0];
	if (!(status & 1))
		printf("Failed to read to socket with AST (2).\n");

	/* Write I/O buffer. */
	status = sys$qiow(3,			/* Event flag */
			channel,			/* Channel number */
			IO$_WRITEVBLK,	/* 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 write to socket.\n");

	/* Shut down the socket (optional). */
	status = sys$qiow(3,
			channel,
			IO$_DEACCESS|IO$M_SHUTDOWN,
			iosb,
			0, 0,
			0, 0, 0,
			UCX$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 socket (optional). */
	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 UCX device channel. */
	status = sys$dassgn(channel);
	if (!(status & 1))
		printf("Failed to deassign the channel.\n");
}

/*-------------------------------*/
/*  Routine connect $QIO. */
/*-------------------------------*/
void connect_ast (void)
{
 int	i;
 int	status;		/* For return status */
 short	iosb[4];	/* I/O status block */

  sys$wake(0,0);
  status = sys$qio (
  		    3,                       		/* Efn			*/
                    channel,           			/* Channel I/O		*/
                    IO$_READVBLK | IO$M_NOECHO, 	/* Func			*/
                    iosb,                    			/* Status Channel	*/
                    read_ast,                			/* Ast routine address	*/
                    0,		        			/* 			*/
                    buffer,     	      			/* Buffer of read	*/
                    1,		    			/* N� Charac. read	*/
                    0,/*&rhst_adrs,*/			/* P3 Remote IP address	*/
/* In parameter P3 used two values (0/&rhst_adrs) */
                    0,                       			/* P4			*/
                    0,                       			/* Prompt		*/
                    0);                      			/* N� Charac. Prompt	*/

	if (status & 1) status = iosb[0];
	if (!(status & 1))
		printf("Failed to connected the AST.\n");

  return;
}

/*-----------------------------------------*/
/*  Routine post another read QIO. */
/*-----------------------------------------*/
 void read_ast(void)
{

 int	status;					/* For return status */
 short	iosb[4];					/* I/O status block */

       	status = sys$qio (
                    3,                       			/* Efn			*/
                    channel,           			/* Channel I/O		*/
                    IO$_READVBLK | IO$M_NOECHO, 	/* Func			*/
                    iosb,                    			/* Status Channel	*/
                    read_ast,                			/* Ast routine address	*/
                    0,		        			/* 			*/
                    buffer,     	      			/* Buffer of read	*/
                    1,		    			/* N� Charac. read	*/
                    0,/*&rhst_adrs,	*/		/* P3 Remote IP address	*/
/* In parameter P3 used two values (0/&rhst_adrs) 	*/
                    0,                       			/* P4			*/
                    0,                       			/* Prompt		*/
                    0);                      			/* N� Charac. Prompt	*/

	if (status & 1) status = iosb[0];
	if (!(status & 1))
		printf("Failed to post another read \n");
        return;
}

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

Dates got after run TCP_QIO

VAX::JOSE> run tcp_qio
Enter remote host Internet address (a.b.c.d):159.23.2.14
Enter remote port number:2015
Failed to post another read
Failed to post another read

Problems
------------ 
1� When TCP_QIO is running, the first call to sys$qio in main program  isn't 
    correct. The program 
continued though the service routine ast_read  without to be executed I/O. 
2� There is a problem in post another read sys$qio with AST. The program state
     is loop. 

Questions
-------------
I need to know information about sys$qio for protocol TCP/IP
    
5337.5UTRTSC::KNOPPERSOswald KnoppersFri Mar 21 1997 03:0764
Hi,

I don't think the example in .-1 makes much sense:

The first asynchronous IO looks like this:

        /* Read I/O buffer. (AST)*/
        status = sys$qio(
                    3,                                          /* Efn                  */
                    channel,                            /* Channel I/O          */
                    IO$_READVBLK | IO$M_NOECHO,         /* Func                 */
                    iosb,                                       /* Status Channel       */
                    read_ast,                                   /* Ast routine address  */
                    0,                                  /* Ast param            */
                    buffer,                                     /* Buffer of read       */
                    1,                                  /* N� Charac. read      */
                    0,/*&rhst_adrs,*/                   /* P3 Remote IP address */
/* In parameter P3 used two values (0/&rhst_adrs) */
                    0,                                          /* P4                   */
                    0,                                          /* Prompt               */
                    0);                                         /* N� Charac. Prompt    */
        if (status & 1) status = iosb[0];
        if (!(status & 1))
                printf("Failed to read to socket with AST (1).\n");

In there is no reason to check the iosb at this time. The only thing you
can do is check the status of the QIO call itself (this will return an error
of parameters are in error or something like that). The iosb will only contain
usefull info *after* the IO has completed. So at this time the application
should call sys$hiber() or start doing something else.

Then in the read_ast routine you start with:

 void read_ast(void)
{

 int    status;                                 /* For return status */
 short  iosb[4];                                        /* I/O status block */

        status = sys$qio (
                    3,                                          /* Efn                  */
                    channel,                            /* Channel I/O          */
                    IO$_READVBLK | IO$M_NOECHO,         /* Func                 */
                    iosb,                                       /* Status Channel       */
                    read_ast,                                   /* Ast routine address  */
                    0,                                          /*                      */
                    buffer,                                     /* Buffer of read       */
                    1,                                  /* N� Charac. read      */
                    0,/*&rhst_adrs,     */              /* P3 Remote IP address */
/* In parameter P3 used two values (0/&rhst_adrs)       */
                    0,                                          /* P4                   */
                    0,                                          /* Prompt               */
                    0);                                         /* N� Charac. Prompt    */

It makes no sense posting a new QIO here. First now you should check the iosb
of the (just completed) IO, then (if ok) the data should be available, process
the data if you like. Decide to either post a new (async) QIO or stop
processing by calling sys$wake() to get the main program going again.

I think you could best sell your customer some consultancy.

Regards,

Oswald
5337.6The last think, an exampleBARNA::DSMAILMon Apr 07 1997 06:2013
    Hi Oswald,
    
    I agree with you that the customer needs a consultancy.
    Butr the customer has analyzed the comments about the program and hi
    says is not relevant the changes that you suggested. I think we don't
    have to expend more time in this case but for customer satisfaction
    would be a good solution only to supply an example like the examples
    supplied in the programmers manual but with TCP. If you know any
    pointer for this will be very helpful.
    
    Thanks a lot for your cooperation.
    
    Crist�bal
5337.7UTRTSC::KNOPPERSOswald KnoppersMon Apr 07 1997 09:431
Example mailed.