Hi Scott,
I switched to using _C_IFS_FREAD and it works much better. I did not notice
that the _C_IFS_FGETS was only for text data or I would not have used it in
the first place.
The only problem I am seeing now is that I am not getting the last 2 bytes
of data. For example, if I have an image that is 34 bytes long, I'm only
getting the first 32 bytes. The image written to the PC is perfect right up
to those missing 2 bytes of data.
It's possible that I'm dropping those last two bytes when they hit the PC,
but just in case it's my RPG program...take a look at this and give me your
opinion on whether or not I coded this correctly for this bit of code
(please):
*--------------------------------------------------------------
D ifsReadByte PR 10i 0 ExtProc('_C_IFS_fread')
D inBuffer * Value
D inUnitSize 10i 0 Value
D inBufLen 10i 0 Value
D inFilePtr * Value
D outBuffer S 32767a
C Dow ifsReadByte(%Addr(outBuffer):
C 2:32767:zp) > 0
C callp(e) WriteDataToSocket(sockDescriptor: outBuffer)
C Enddo
The parameter here that confuses me (mostly because I cannot find enough
good documentation on it that I can understand) is the inUnitSize. I
thought I understood what that meant, (i.e., Size in bytes of each element
to be read.), but it does not seem to make a difference what size I make
that, as long as it's not 1. So I'm thinking I don't really understand how
the inUnitSize and inBuflen work together.
I'm not translating to EBCDIC and then back to ASCII or doing any
translation at all, by the way.
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx]
On Behalf Of Scott Klement
Sent: Wednesday, November 28, 2007 5:48 PM
To: RPG programming on the AS400 / iSeries
Subject: Re: Send_File API versus Send API over a Socket
Shannon,
The fgets() API (i.e. _C_IFS_fgets for IFS files) is designed for
reading TEXT files. Hopefully you understand the difference between
text data and binary data -- if not, please ask and I'll explain.
Since an image file is NOT text data, these APIs are not suitable for
reading it.
Either use the fread() (err... _C_IFS_fread) API, to read the file (and
if you do, make sure you use the 'b' flag on fopen() to tell the system
to read in binary mode, as well).
Or change your code to call the system IFS APIs open() and read() to
read the file (instead of the ILE C fopen() and fread() APIs). If you
do use this approach, please make sure that you do NOT specify
O_TEXTDATA -- because, again -- image files are not text data.
My suspicion of your problem is that you're either mistranslating the
data (i.e. translating it from ASCII to EBCDIC with fgets() and then
manually translating it back) and therefore corrupting the data
(translation from EBCDIC to ASCII and vice-versa makes no sense on
binary data.) OR your image file contains nulls (x'00') which would
make it impossible to determine the length of the data when using
fgets().... making it likely that you're simply discarding any bytes
after any x'00' in each block.
send_file() is the equivalent of calling read() and send() in a loop.
You still have to call the open(), socket(), and connect() APIs
manually, and you still have to remember to exclude O_TEXTDATA from the
open() call. send_data() can also close() the socket when it's
done.... but you still have to call close() on the IFS file.
Frankly, I never use send_data() for the simple reason that the
operating system takes control during the entire send of the file. This
deprives me of the ability to show a "progress meter" to the user that
details how much of the file has been sent, and how much is remaining,
and other good stuff like that. Since it's not difficult to code a
loop between read() and send(), I just go ahead and code the loop.
Send_File() really doesn't save me much work.
I'm almost certain that your problem has nothing to do with the
difference between send_file() and send() -- but rather that you're
reading the IFS file as if it's a text file, when it's clearly not!
sodonnell@xxxxxxxxxxxxxxxxxxxxxxxxx wrote:
Hello,
I have an application that reads an image file off of the IFS (it's a TIFF
file if that makes a difference...) and then I send it to a PC over a
socket.
I'm using the _C_IFS_OPEN and _C_IFS_GETS to read the file and I'm using
the Unix-type API Send to send the file across the socket.
The problem I'm having is that somewhere along the way, my image file is
getting corrupted. That is, the first few lines of the image data are fine,
and in fact, you can even make out a little bit of what the image is if
you look at it in Windows. But somewhere between the last point where I have
good data and the end of the file (or possibly including the end of the
file too), my image data gets altered.
If I look at the file in Notepad or Wordpad or even in a DOS prompt, I can
see that the data is MOSTLY correct. however, there are places where the
data is obviously different. And since it's in hex (or whatever...) it's
impossible for me to look at it and say, "Oh, there's a line feed or
carriage
return there where there shouldn't be."
So, what I'm wondering is... If I used the Send_File API (instead of SEND
and the _OPEN and _GETS APIs (as shown above)), do you think my chances of
avoiding trashed data would improve? I guess I could just try it and see
but I was hoping someone might have used Send_File before and had some
experience with it.
There are 3 distinct points where the data could be getting hosed in this
process:
1. When I read the data using the _C_IFS_GETS API.
2. When the data is sent across the socket from my RPGLE program.
3. When the data is received at the socket server.
The last one does not seem as likely simply because that process has
worked flawlessly for years. On the other hand, I don't know if I've ever
send
an image file like this before to it. This might be a first for me as it's
been awhile since I messed with any of this, I don't really remember.
It seems more likely to me that the problem is either in the Read or the
file from the IFS or it's in the send across the socket.
Thoughts, opinions suggestions and anything else is welcome.
thanks,
Shannon O'Donnell
As an Amazon Associate we earn from qualifying purchases.