Re: Question about CSocket::Receive()

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



In message <2tt4b21fnnaovbhic7r62eajpd1c99r93o@xxxxxxx>, Joseph M. Newcomer <newcomer@xxxxxxxxxxxx> writes
Just because it is documented doesn't mean it is the best choice.

Agreed.


In fact, it is usually
the worst.

"Usually" seems a bit extreme.


It is rumored that CSocket itself doesn't actually work due to bugs in the MFC
implementaiton; I wouldn't know, I've never used it, and I've been programming sockets for
about eight years. See below...
On Mon, 10 Jul 2006 08:03:08 +0100, Fenster <fenster@xxxxxxxxxxxxx> wrote:

In message <78vsa2pvf963ot399thjp2f485jbl9path@xxxxxxx>, Joseph M.
Newcomer <newcomer@xxxxxxxxxxxx> writes
That's your first mistake: you have a class derived from CSocket. This
is almost always a
mistake; you should not be using synchronous sockets for any purpose.

Thanks for your kind words. When I wrote my application, my first to
use sockets and fairly simple, in the grand scheme of things, I went
straight to the documentation where I found mfcsocs.exe, hence the
CSocket roots.

Use CAsynchSocket.

I'll give it a spin, thanks.

Note that when you do a Receive, you get some number of bytes. The
number of bytes you
receive is unrelated to any number of bytes that have been sent;

I was aware of that.

you are responsible for
doing enough Receive operations to receive all the bytes.

Really? Being responsible for and actually getting all the bytes (for
whatever reason) are not the same thing. Hence my question, do I get
one stab at Receive() for a particular set of bytes that have
"triggered" an OnReceive() or can I get as many as I can handle this
time and get the rest later or will they be lost?
****
TCP/IP is a "reliable" network communication mechanism. This means that if you do enough
Receive calls, you will receive all the bytes sent, in the order sent, with no drops and
no duplications. The general wisdom is that you do exactly one Receive call in each
OnReceive,

This is the confirmation that I was after from my original post because I had vague recollection that I'd read it somewhere and then couldn't find it. I began to think that I'd imagined it.

The "CSocket bad, CAsyncSocket better" stuff is an added bonus.


and what you would do is know, by some means or other, how many bytes you
*should* receive, and consequently you do not act upon the bytes received until you have
had enough OnReceive calls to account for all the bytes you were supposed to receive.

It is the nature of TCP/IP that later bytes will not be lost; they will trigger another
OnReceive at some indefinite point in the future, and you can receive them then.
*****

It seems, from Scott's post, that I will be able to get them later and
that no data should be lost. Whether or not I should be letting the
data sit around is another story...
****
That's right. If you are "message oriented" you have to receive an entire "message"
(whatever that means to you!) before processing it, and this means you have to keep the
initial parts of the message around, somewhere, until you receive all of it. Whether or
not you can let data "sit around" is based on what you are doing with the data, and what
it means to have just part of it.

There are many ways to do this. The most common way is to prefix the message with a count
of the number of bytes in it. By tradition, if this is a binary value (16 or 32 bit, for
example) you would put it in Network Standard Byte Order (big-endian) and you would use
htons or htonl to convert from native to NSBO, and ntohs or ntohl to convert from NSBO to
native on the receiving side. You must also plan on the fact that if you ask to read 2 or
4 bytes of header that you may get 1 byte of the 2-byte length or 1, 2, or 3 bytes of the
4-byte length, and therefore you have to plan on how to deal with partial receipt of
length.

In one app, where the sender was VB (which makes binary big-endian byte order painful) we
simply sent the length as four characters followed by a semicolon (to add some redundcany
and error checking, e.g.,
0011;Hello world0007;goodbye0000;
where the 0000; meant "end of transmission" and I would disconnect the socket upon
receiving it. Same problem applies; I could get 1, 2, or 3 bytes of the length and
couldn't decode it until I had all 4 bytes.

You can alternatively say that each "message" is terminated by a newline, or NUL, or EOB,
or some other convention of your own. In this case, you would have to parse the message
and return the segment up to the terminator; if no terminator was found, you hold onto it
until subsequent Receive calls add enough bytes to find a terminator. Then you have to
save everything after the terminator, parse it (in case you get multiple messages per
Receive), etc., but this is all just straightforward programming. I tend to use
PostMessage to deliver the packets to whomever cares about them.

Can I assume that messages sent by PostMessage() will arrive in the order they were sent (and not undo the good work by the "reliable" TCP/IP)?


*****

It is your responsibility to
see that you handle concatenating the bytes to form a complete sequence
of bytes.

I was aware of that too.

This is
just elementary programming.

It is. Thanks.
joe

On Fri, 7 Jul 2006 16:02:16 +0100, Fenster <fenster@xxxxxxxxxxxxx> wrote:


I have a class derived from CSocket.

I have a vague recollection that I only get one shot at calling
Receive() in my override of OnReceive(). What I mean by that is that if
there's 2k of data to be read but I only read 1k when I call Receive()
then the other 1k gets lost.

Or can I call Receive() more than once within OnReceive() but after I
exit OnReceive() I lose any data that didn't read?

I can't remember where I've read this or something along those lines and
I can't see it in the documentation. It may be that I'm completely
mistaken and it's just my memory playing tricks on me.

Can anyone help me out with this? Thanks.
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

--
Fenster
.



Relevant Pages

  • Re: RMI vs. Sockets vs. ?
    ... RMI is easier than socket programming, ... But sockets can help to connect with application written ... Neglecting for a microsecond the labor cost of creating the apps, by the time you compare the parsing, error-handling and related tasks for a custom message infrastructure against a SOAP-based one with, say Apache and Sun tools, you may find that message sizes are not quite so different, and processing costs closer still. ... Undoubtedly SOAP messages would require more bytes than "equivalent" custom-format compact messages; I'd be dubious of claims that there are significant differences in "speed" once a message reaches its destination. ...
    (comp.lang.java.programmer)
  • Re: Implementations for parallel programming?
    ... construct a means for separate instances of Wraith Scheme, ... that communicate using Unix Sockets. ... I have often requested people on the Bigloo ... use Bigloo for parallel programming task. ...
    (comp.lang.scheme)
  • Re: C Sockets Newbie: Easy question
    ... If this is an exam question for a sockets course, ... either the file descriptor of the open file (which is a small number ... "Unix Network Programming" by Stevens. ...
    (comp.unix.programmer)
  • Re: Batch connection to CSKL (was: Trigger CICS transaction from Batch Job)
    ... You can find the fine manual that describes the CICS side of such at z/OS ... in z/OS Communications Server IP Sockets Application Programming Interface ... transaction) that makes managing a listener in CICS quite simple and effective. ... All you need to do is to code the child server transaction in your programming ...
    (bit.listserv.ibm-main)
  • Re: UDP messages lost in Ip-stack ?
    ... Each message has a sequence number. ... If a message is lost, the receiver will get an incorrect ... A network listener is used to monitor the traffic. ... I also wrote a simple listener using raw sockets. ...
    (microsoft.public.win32.programmer.kernel)