× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Michael,

If you are in blocking mode (the default) and you call the recv() API, the system won't return control back to your program until there's data to return. This is referred to as "blocking." The term "blocking" essentially means that the OS has stopped execution of your program, waiting for some event to occur.

If you put the socket in non-blocking mode, it won't ever wait. If there's data available at the instant when you call recv(), you'll get it. If there isn't any data, you'll get back control immediately, but recv() will return <1, and errno=EWOULDBLOCK. (Or, EAGAIN, which means the same thing.)

If you want to call recv() and have it wait for data, but time-out after a period of time if no data arrives, then you might appreciate this article:
http://systeminetwork.com/article/timeouts-sockets-0

For the type of application you're writing, you might consider refactoring it into an event-driven model. The main loop would look somethhing like this:

socket()
connect()

dow connected;
FD_ZERO(readset);
FD_ZERO(writeset);
FD_SET(mysock: readset);
if (theres_data_to_write);
FD_SET(mysock: writeset);
endif;
n = select( mysock+1
: %addr(readset)
: %addr(writeset)
: *null
: *null );
if (n < 1);
// handle error
endif;
if FD_ISSET(mysock: readset);
recv();
// if error, set connected=0
call program_logic();
endif;
if FD_ISSET(mysock: writeset);
send();
// if error, set connected=0
endif;
enddo;

The idea is that your program is constantly trying to send/receive data from the host. When your main program logic has data to send, it puts it in the send buffer, and the main loop takes care of the actual sending.

When data is received, your main loop receives the data into a buffer. Then calls your program's logic.

What I mean by "event driven" is that your program logic is only called when something happens. (As coded above, it'd only be called when new data appears on the wire. But you could easily change this to have it called on a particular time interval even if no data is received.)

Your code would be designed to do whatever it needs to do without stopping, and then return control back to the main loop. Maybe you scan for the string you're looking for... and if found, process it... but then go back to the main loop. You never get hung up waiting for data, you just look for data you need, and if it's not there, you go back to waiting.

Not sure if that fits your scenario or not, but sounds like it would. Aside from a scenario like this, I can't think of any situation where you wouldn't know when your "command" is finished!


On 3/2/2011 3:54 PM, Koester, Michael wrote:
Don't know if this is related, but I also am having trouble with recv().
Since I don't know when I've received everything that will be sent (from
telephone switch equipment), if I don't find the expected string in the
buffer, I save what I've received so far and call recv() again. This
seems to work to get additional data when I'm trying to check results
too soon, but I suspect when there's nothing more to be sent (how would
I know?), and I call recv() again, control does not return to my RPG
program.
Has recv() timed out? I have to crash the job, which leaves a
connection to the switch open and messes to clean up.
I haven't done anything fancy with recv(). The line that locks up is:

rc = recv(sock: %addr(recbuf):3000:0);

I send the request to the switch with "send(sock: %addr(request):
reqlen:0)", and then execute a dou loop to interpret the response from
the switch:
Dou done;
[wait a bit]
Recbuf = *blanks;
rc = recv(sock: %addr(recbuf):3000:0);
[translate recbuf to EBCDIC and scan for expected prompt
string]
[If found, leave do loop - else, repeat loop up to a
reasonable number of times]
Enddo;

Debug confirms that it hangs on recv(). Works well so long as the
expected prompt is returned, but I can't process the "not found"
condition if I don't know that there isn't more to receive...

Suggestions welcome!
Michael

-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Wednesday, February 23, 2011 3:50 PM
To: RPG programming on the IBM i / System i
Subject: Re: Socket Recv Question

Have you disabled Nagle's algorithm? That may be throwing off your
benchmarks.

On 2/23/2011 2:31 PM, Zachary Johnson wrote:

Hi Scott, thanks for the reply. Yes, using SOCK_STREAM. I still
think it's odd though that the short request would take longer to
arrive on the socket than the large request. It's driving me up the
wall that I have no other explanation other than "that's how it
works". Thanks again for the response.



As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.