Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

non-blocking socket reads

 
Andrew Skaar
Occasional Advisor

non-blocking socket reads

I have a networking application that utilizes sockets via Compac C V6.5-001 on OpenVMS Alpha 7.3-2 for which I have attempted to use non-blocking I/O via fcntrl, ioctl, and then $QIO.
The fcntrl and ioctl are apparently not implemented on OpenVMS so I replace same with a call to a $QIO IO$_SETMODE with TCPIP$C_IOCTL parameter type and value of 1. The $QIO returned SS$NORMAL and the iosb returned a indication that the TCPIP$C_IOCTL subfunction had executed appropriately by returning SS$NORMAL in its status and the desciptors address in the iosb address field.

The read still blocks. Are there privileges required? And/or is there an example of this specific attribute being set from C with $QIO to illustrate a programming error on my part?
9 REPLIES 9
John Gillings
Honored Contributor

Re: non-blocking socket reads

Andrew,

I'm assuming a non-blocking socket read means you attempt to read from the socket, but if there is no data to be read, the operation returns immediately with some kind of failure status?

If that's the case, then rather than attempting to force fit OpenVMS to a polling model, you'd be better off writing your code to use a more OpenVMS like model.

Rather than polling, the "OpenVMS way" would be to issue an asynchronous read against the socket and specify an AST routine to execute when it completes. The main line code can do other things, or just hibernate waiting for completion.

You could use a very short timeout, to get the same effect, but the $QIO socket interface doesn't implement one directly, so you need to use a timer AST for your timeout period and $CANCEL on the socket channel.

That said, does your $QIO READVBLK include the flag TCPIP$C_MSG_NBIO? "Does not block the I/O operation if the receive queue is empty (similar to using IO$M_NOWAIT)."

If none of that helps, please post your actual code for the read operation.
A crucible of informative mistakes
Steven Schweda
Honored Contributor

Re: non-blocking socket reads

I know nothing, but as a start:

TCPIP SHOW VERSION

This probably matters more than the C
compiler version.

> The fcntrl and ioctl are apparently not
> implemented [...]

Which fcntrl() and ioctl()? Apparent to
whom? Why? What, exactly, did not work?
How about fcntl()? (I'd guess that ioctl()
has a better chance on a socket than fcntl()
does.) I do see FIONBIO in .

> The $QIO [...]

With my weak psychic powers, I can't see that
code, either.

> Are there privileges required?

Not likely.

> [...] an example [...]

I see FIONBIO in the cURL code, but I don't
know if it's used on VMS.

A Web search for, say,
vms OR openvms socket blocking
or
vms OR openvms FIONBIO
might find more.
Andrew Skaar
Occasional Advisor

Re: non-blocking socket reads

John,

Thank you for your response. I had considered the first suggestion but due to having my application already up and running with no other issues I had hoped to make one quick change to catch a lost connection that occurred between poll time and read time. the fcntrl, ioctl, or $QIO methods all seemed like quick and easy fixes to accomnplish the goal.

I mixed standard C socket programming with one call to a $QIO to accomplish this. Is there something that prohibits this? I have wondered why this ioctl function does not seem to be implemented on OpenVMS. You mentioned the Readvbk $QIO. Would this be necessary for me to do this approach?

I don't mean to be intractable but I am just a little frustrated by what appears like it should work.

BTW, I do catch the loss of network connection on the attempted writes. My kludge doesn't appear to have any real deficit but perhaps I am just ignorant of what it is.

Your first paragraph was correct except that I am not looking for a failure status just no data. TCP/IP does not return a status for lost connections unless explicitly closed by the peer (I believe).
Andrew Skaar
Occasional Advisor

Re: non-blocking socket reads

Steven:

I am sorry. I typo'ed on the fcntrl, I meant fcntl. As to your pyschic powers, I apologize again, I meant setting the non-blocking attributes from these functions does not appear to be implemented on OpenVMS.

It appeared that way to me because of the not implemented status returned to me from the function calls and from a few internet posted that had indicated such. If my research is incomplete and my interpretation of the function returns is incorrect, I again apologize.

I too found the FIONBIO in the ".h" file and thought it odd that they would define the constant yet not implement the functionality associated with it. I thought that it might have been for completeness or future intent.

I often belabor people with too much detail and tried to avoid this by posing the statement about the $QIO call as if it could be assumed that I probably did the basic call correctly. This, I admit, is something of an assumption but I do believe that it is correct. My VMS is 10+ years rusty and I certainly could have messed it up but the iosb returned seemed to indicate that it is not a bad assumption.
Martin Vorlaender
Honored Contributor

Re: non-blocking socket reads

Andrew,

I recently faced the same issue when porting the current version of NRPE. While struggling with the TCP/IP services documentation, I found http://h71000.www7.hp.com/doc/82final/6529/6529pro_013.html#r_accept

where it says

If the socket is marked nonblocking by using a setsockopt() call and no pending connections are present on the queue, accept() returns an error.

BUT: the setsockopt() documentation doesn't provide any information about using it to set the socket to non-blocking.

I then found ioctl and FIONBIO and http://h71000.www7.hp.com/doc/82final/6529/6529pro_029.html#app_ioctl_commands

and my debugging experiences seem to show it wworks.

Along the lines of

int flag=1;
...
ioctl(sock,FIONBIO,&flag);
...
while (1){
/* wait until there's something to do */
FD_ZERO(&fdread);
FD_SET(sock,&fdread);
timeout.tv_sec=0;
timeout.tv_usec=500000;
retval=select(sock+1,&fdread,NULL,&fdread,&timeout);

/* accept a new connection request */
new_sd=accept(sock,0,0);
if(new_sd<0){
/* retry */
if(errno==EWOULDBLOCK || errno==EINTR)
continue;
/* socket is nonblocking and we don't have a connection yet */
if(errno==EAGAIN)
continue;
}
...
}

HTH,
Martin
Andrew Skaar
Occasional Advisor

Re: non-blocking socket reads

Thanks, Martin. I will check it out. It is not exactly what I am looking at but it may help.
Andrew Skaar
Occasional Advisor

Re: non-blocking socket reads

Steven:

There is a requirement to have a system UIC or have sysprv, bypass, or oper privileges to do a setting of parameters with a $QIO's IOCTL call. We are pretty locked down here but I do have oper privilege so this is not my issue. I would guess that this is a restriction on the C API ioctl call as well.

BTW, my TCPIP version is V5.4 ECO5.

To correct a mis-statement of mine, my calls to fcntl return a bad parameter error code to errno. My ioctl appeared to work and returned a good status as a function return and to errno but still blocked on the read. My call to $qio setmode did the same, good returns, no effect.

I will post some code soon if I have not figured it out.

As an aside, I define my socket, setsockopt, ioctl, and then connect. There is no requirement to connect before calling the ioctl is there?
Highlighted
Andrew Skaar
Occasional Advisor

Re: non-blocking socket reads

Thank you all, I have found my programming error. I was doing what I was attempting correctly but had imposed a different error and did not recognize the proper source of the error.
Andrew Skaar
Occasional Advisor

Re: non-blocking socket reads

I have found the solution to my problem. The respondants were helpful but my error was of a different nature.