| 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
|
| 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
|