hi Jerry,
Since my buffer may only provide the first 1392 bytes (out of the
total 1869 bytes which composes my first complete message), I can do
the read in a loop and look for CRLF.
I want to emphasize that the 1392 is due to your current circumstances,
and these circumstances are made up of many different factors. The MSS
of all of the network interfaces & routers involved in the conversation
is the biggest factor, but the speed of the computer can also be a
factor. You don't want your program to break every time someone makes a
minor change to your network configuration. (Or the configuration of
the comptuer you're talking to, or the configuration of a router, etc.)
If the maximum size is 4k, then write your code to read the socket in a
loop until you either get a total of 4k, or you get a CRLF. Don't rely
on the size being 1392. (I think you know that, but I wanted to make
sure it's clear.)
Once I detect CRLF, I need to send an acknowledgement string back to
the client. If the socket stream/buffer(?) from my subsequent read
contains data that belongs to a new message (to be processed after
sending the acknowledgement to the client), will my write operation
back to the client overlay the existing data received by the last
read? Or are the read and write buffers separated as to prevent
collision?
TCP sockets have separate buffers for read & write. A write will never
overlay a read or vice-versa. TCP is a full-duplex protocol, it allows
simultaneous reading and writing (in an extreme case, one job could be
reading the socket while another one is writing so they're happening at
exactly the same time!)
However, the danger behind reading until you get CRLF is that you could
(at least, the potential is there) read, for example, 100 bytes and have
the CRLF be in bytes 33 & 34. So bytes 1-32 would be in the message
you're reading because they come before the CRLF and bytes 35-100 are
part of the next message.
You could solve that problem by reading the socket 1-byte at a time, but
then you run into performance issues.
So typically you'd solve that problem by saving the leftover data in a
variable and adding it to the next message when that comes up.
Fortunately, most application protocols don't have this problem because
each time they send a string (with CRLF at the end) they stop and wait
for an acknowledgement before sending the next one. Consequently, you
can't possibly have the next message in the buffer, since it won't send
the next message until you tell it to.
I only mention this because it's a potential "gotcha". IOW, if your
protocol does allow for multiple messages without any sort of go-ahead
or acknowledgement, then you'll have to write your code so that it
potentially can get part of the next message after the CRLF, and handle
it appropriately. If it's a protocol that you're designing, you may
want to design it so that this can't happen.
Also when I read (into a variable length field), my first two bytes
are missing. I suspect that those first two bytes are the
representation of the length of the data. But I can't for the life of
me manipulate the data to get it to start at the actual beginning of
the data.
That kinda sounds like you're reading into an RPG "VARYING" type field.
(Which is a variable-length field, yes, but in my mind
"variable-length" is a more general term that can mean many things,
whereas "VARYING" is a specific data type.)
If you're reading into an RPG VARYING field you need to follow these steps:
a) Set the field to it's maximum length before calling the recv() API.
Generally the code to do that looks like this:
%len(Field) = %size(Field) - 2;
b) Call the recv() API, but pass the address of the DATA, not the
address of the length. Basically, add 2 to the adddress. Typically,
you'd code it as follows:
len = recv(mySock: %addr(Field)+2: %len(Field): 0);
c) Then, if the recv() API didn't return an error, set the length of the
varying field appropriately:
if (len = -1);
// handle error
else;
%len(Field) = len;
endif;
Good luck
As an Amazon Associate we earn from qualifying purchases.