|
Thanks Scott. I'm going to assume that since it works correctly for you that it's probably my network doing something strange. I'd like to try this at work during the day but I'm afraid that I'd get in trouble for playing with this during work hours. They are pretty strict on that, although I can get on through the web after hours so I don't know what's the difference. Corporate policies... Can I ask one more question? Well, maybe it's two questions. Is there any setting on the AS/400 that will allow you to make a failed socket connection to drop faster than whatever the default rate is? I'm thinking that if my program attempts to connect to a socket server and it cannot, or if it does connect and then later cannot send (maybe the connection dropped or something...who knows...) is there some way I could force the connection or send attempt to stop at some predetermined time limit rather than the system default and have the user just sit there and wait and wait and wait until it finally gives up? I was thinking that the socket linger routiines you gave as examples would handle this for me but I wasn't absolutely sure about that. Thanks again! Scott Klement <rpg400-l@xxxxxxxxxxxxxxxx> wrote: Hi Dave, The code you posted got cut off because it was too long. Since you don't use the RdLine() routine, and you use WrLine() only once and it's not realted to the problem, I just omitted that code. I added the /DEFINE ERRNO_LOAD_PROCEDURE and /COPY ERRNO_H to the bottom of the code and compiled it on my system. However, when I run your code, the connect() API returns -1 and the program ends, just as expected. I'm at V5R3. I'm behind on PTFs by, oh, probably 6 months. My iSeries does not use satellite (it uses a fractional T1) but I don't see why that'd matter. I agree that trying a different Internet connection might help debug things. Or maybe just take a PC into the office during off hours and connect it directly to the iSeries (with a hub/switch in between or with a crossover cable) and do the tests straight from the iSeries to the PC with nothing in the middle. Heck, just trying it with another computer on the LAN would probably be adequate. - - - There are a bunch of things I didn't like in your code (I'm a little picky) I'll tell you what they are so you can decide whether you'd like to take my advice and change them: >From your code sample: D addrCvtr PR 10U 0 extproc('inet_addr') D 15A options(*varsize) const This is wrong. The inet_addr() API requires a null-terminated string, but this prototype doesn't do that. The code will work 99% of the time because most of the unallocated memory on the iSeries is filled with null characters... but, you don't want your code to fail 1% of the time with weird errors that are difficult to debug :) The prototype SHOULD look like the following one: D addrCvtr PR 10U 0 extproc('inet_addr') D * value options(*string) Note that you already have the correct prototype for inet_addr in your source member with the above definition, but it's called inet_addr() rather than renaming it to addrCvtr(). IMHO, it's a bad idea to rename it like this. Why should you call it "inet_addr" instead of "addrCvtr"? To be kind to me (or people like me) when I read your code. :) When someone sees "addrCvtr" in your code, what will they do? Since that's a name of your devising, it won't be familiar to them, and they'll have to search around to find it. Maybe they'll search the Information Center (as I did) and find no hits. Maybe they'll search the web and find nothing. Eventually they'll find in your code where you renamed inet_addr() to addrCvtr() but why put them through that? All of the documentation refers to the API as inet_addr(). It's called inet_addr not only on the iSeries, but on Unix, Windows, etc, etc. It's a standard API used all over the place. It's just easier to follow your code when you don't rename it like that. Another thing that doesn't make sense, but isn't causing a problem: C Eval I_Net_Adr = %trim(I_Net_Adr) What was this code intended to do? I_Net_Adr is a fixed-length 20A field. When you do RtvNetAds(device) it assigns an IP address to this field. So prior to the above %trim() statement it'll look something like this: '192.168.100.100 ' The %trim() BIF will remove those 5 blanks from the right-hand side of the string, making it 15 chars long. Since it's only 15 chars long, the EVAL operation will add 5 blanks to the end in order to make it fit in a 20A field? The result is that you just stripped off the 5 blanks and added them back, creating a little bit of work for the computer, but accomplishing nothing. You can just omit that line of code, since it doesn't do anything. (Granted, it doesn't hurt anything, either, but why do it?) There's a similar problem later in your code: C Eval bufOut = *Blanks C Eval bufOut = %Trimr(bufOut) + C 'MYDATAGOESHERE' This is what that code does: a) Take the BufOut field, which contains 32k worth of blanks, and replace all 32767 blanks with new blanks. (Taking some CPU time, but accomplishing nothing.) b) Use the %trimr() BIF to remove those 32767 blanks that you just added. c) Put 'MYDATAGOESHERE' at the start of the string, and then add 32753 blanks on to the end. You can solve the problem by simply coding: C Eval bufOut = 'MYDATAGOESHERE' You also appear to have most (if not all) of the code from my SOCKET_H member included directly in your program. In my opinion, that makes the code more difficult to read because it makes the source member significantly longer, and therefore is more stuff for the next programmer to take in. Just use /COPY to bring in the definitions (like you did for ERRNO_H and SOCKUTIL_H) Not only that, but putting them in a separate source member makes the next socket related program easier to write since you don't have to copy the code from member to member. You can just use the same /copy statement in the new program You also have multiple ways to retrieve "errno" in the code. You have mine, and you have $$Errno. I'd recommend picking one and using that method exclusively... it's confusing to have two of them. You also have prototypes for the read() and write() with comments saying that you'll use them to read and write from the socket. If you want to use those APIs, you can, they'll work just fine. but I recommend putting them in a /copy member, and then not using send() and recv() in the code. There's no reason to use both, and having them both in your program's definitions is confusing. And you have unlink(). Were you planning to delete files from the IFS? I didn't see any mention of it in the code you posted. Again, the fact that it's there just adds to the confusion... if you don't need it, why's it there? Sorry for being long-winded, and I hope my words above are helpful. --- Scott Klement http://www.scottklement.com On Sun, 5 Feb 2006, Dave Johnson wrote: > Scott, thank you for helping me try to understand this. I've posted the > program code on midrange.com here: > http://code.midrange.com/index.php?id=86383b016d > > That's my entire program. I realize it's full of a lot of extraneous > procedures that are not even used here, but I just copied your copy > books in so I wouldn't miss anything. The shotgun approach. > > I changed the socket(xxxx call to use literals instead of the constants, > even though I'm sure the constants were fine. BUt just to be sure you > know. > > If it makes any difference at all... I am connected to my iseries over a > two-way satellite using a satellite modem. I don't know why that would > matter but maybe direcway does some weird stuff there. > > I wish I had a dial up account somewhere so I could test this that way > and see if I get the same results. That'd tell me for sure that's its > something on my modem or network or connection that's causing the > problem if the dial up worked. > > Thanks, > > Dave Johnson
As an Amazon Associate we earn from qualifying purchases.
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.