Question about CSocket::Receive()

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.

-- 
Fenster
0
fenster (60)
7/7/2006 3:02:16 PM
vc.mfc 33608 articles. 0 followers. Follow

11 Replies
809 Views

Similar Articles

[PageSpeed] 38

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.  Use CAsynchSocket.

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; you are responsible for
doing enough Receive operations to receive all the bytes.  It is your responsibility to
see that you handle concatenating the bytes to form a complete sequence of bytes.  This is
just elementary programming.
				joe

On Fri, 7 Jul 2006 16:02:16 +0100, Fenster <fenster@croctec.co.uk> 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@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15972)
7/7/2006 3:28:46 PM
Fenster 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.
> 

You should only call Receive once, but if you don't take all the data 
that it has nothing is lost.  If will just call your OnReceive again if 
necessary.

I, too, would suggest CAsyncSocket instead of CSocket.  CSocket has a 
terrible reputation and does not fit in well with an event driven 
application.

-- 
Scott McPhillips [VC++ MVP]

0
Scott
7/7/2006 4:48:09 PM
"Fenster" <fenster@croctec.co.uk> wrote in message
news:nL5p4mB4dnrEFwnQ@FensterPC.croctec.co.uk...
>
> 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.
>
> -- 
> Fenster

Best recommended practice for your OnReceive override is to call Receive()
exactly once.  This is clearly part of the documentation.  See
http://msdn2.microsoft.com/en-us/library/ct7d990b.aspx which states:
"Receive should be called only once for each time CAsyncSocket::OnReceive is
called."

You will not lose the un-received data.  Instead, you will get another call
to OnReceive a bit later, and you will have another opportunity to call
Receive() again then.  The documentation for WSAAsyncSelect explains this at
http://msdn.microsoft.com/library/en-us/winsock/winsock/wsaasyncselect_2.asp

See also http://support.microsoft.com/kb/185728/en-us

Despite its detractors, CSocket is fine for simple tasks and a small number
of connections.  On the other hand, if you intend to use it with a CArchive,
or a CSocketFile, just don't.


0
7/7/2006 6:18:34 PM
In message <78vsa2pvf963ot399thjp2f485jbl9path@4ax.com>, Joseph M. 
Newcomer <newcomer@flounder.com> 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?

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...

>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@croctec.co.uk> 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@flounder.com
>Web: http://www.flounder.com
>MVP Tips: http://www.flounder.com/mvp_tips.htm

-- 
Fenster
0
fenster (60)
7/10/2006 7:03:08 AM
In message <#UEZiUeoGHA.516@TK2MSFTNGP05.phx.gbl>, "Scott McPhillips 
[MVP]" <org-dot-mvps-at-scottmcp@?.?.invalid> writes
>Fenster 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.
>>
>
>You should only call Receive once, but if you don't take all the data 
>that it has nothing is lost.  If will just call your OnReceive again if 
>necessary.
>
Thanks a lot Scott.

>I, too, would suggest CAsyncSocket instead of CSocket.  CSocket has a 
>terrible reputation and does not fit in well with an event driven 
>application.
>
I shall rebuild today.  Thanks again.

This does lead me to another question though; should I expect two 
applications using stream sockets, one based on CSocket and one based on 
CAsyncSocket, to be able to communicate?

-- 
Fenster
0
fenster (60)
7/10/2006 7:08:27 AM
In message <#9EAGHfoGHA.4024@TK2MSFTNGP03.phx.gbl>, Michael K. O'Neill 
<MikeAThon2000@nospam.hotmail.com> writes
>
>"Fenster" <fenster@croctec.co.uk> wrote in message
>news:nL5p4mB4dnrEFwnQ@FensterPC.croctec.co.uk...
>>
>> 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.
>>
>> --
>> Fenster
>
>Best recommended practice for your OnReceive override is to call Receive()
>exactly once.  This is clearly part of the documentation.  See
>http://msdn2.microsoft.com/en-us/library/ct7d990b.aspx which states:
>"Receive should be called only once for each time CAsyncSocket::OnReceive is
>called."
>
>You will not lose the un-received data.  Instead, you will get another call
>to OnReceive a bit later, and you will have another opportunity to call
>Receive() again then.  The documentation for WSAAsyncSelect explains this at
>http://msdn.microsoft.com/library/en-us/winsock/winsock/wsaasyncselect_2.asp
>
Thanks for that.

>See also http://support.microsoft.com/kb/185728/en-us
>
>Despite its detractors, CSocket is fine for simple tasks and a small number
>of connections.

Controversial. ;)

>  On the other hand, if you intend to use it with a CArchive,
>or a CSocketFile, just don't.
>
>

-- 
Fenster
0
fenster (60)
7/10/2006 7:13:42 AM
Fenster wrote:
>> I, too, would suggest CAsyncSocket instead of CSocket.  CSocket has a 
>> terrible reputation and does not fit in well with an event driven 
>> application.
>>
> I shall rebuild today.  Thanks again.
> 
> This does lead me to another question though; should I expect two 
> applications using stream sockets, one based on CSocket and one based on 
> CAsyncSocket, to be able to communicate?
> 

Yes.  (Assuming that the CSocket application is not encoding the 
messages with CArchive/CSocketFile.)

-- 
Scott McPhillips [VC++ MVP]

0
Scott
7/10/2006 1:07:12 PM
Just because it is documented doesn't mean it is the best choice.  In fact, it is usually
the worst.  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@croctec.co.uk> wrote:

>In message <78vsa2pvf963ot399thjp2f485jbl9path@4ax.com>, Joseph M. 
>Newcomer <newcomer@flounder.com> 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, 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.
*****
>
>>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@croctec.co.uk> 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@flounder.com
>>Web: http://www.flounder.com
>>MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15972)
7/10/2006 4:04:44 PM
The protocol of transmission doesn't care how the bytes are sent; synchronous vs.
asynchronous is an illusion maintained by the I/O manager at the application level.  The
protocol only cares about packets.
				joe

On Mon, 10 Jul 2006 08:08:27 +0100, Fenster <fenster@croctec.co.uk> wrote:

>In message <#UEZiUeoGHA.516@TK2MSFTNGP05.phx.gbl>, "Scott McPhillips 
>[MVP]" <org-dot-mvps-at-scottmcp@?.?.invalid> writes
>>Fenster 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.
>>>
>>
>>You should only call Receive once, but if you don't take all the data 
>>that it has nothing is lost.  If will just call your OnReceive again if 
>>necessary.
>>
>Thanks a lot Scott.
>
>>I, too, would suggest CAsyncSocket instead of CSocket.  CSocket has a 
>>terrible reputation and does not fit in well with an event driven 
>>application.
>>
>I shall rebuild today.  Thanks again.
>
>This does lead me to another question though; should I expect two 
>applications using stream sockets, one based on CSocket and one based on 
>CAsyncSocket, to be able to communicate?
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15972)
7/10/2006 4:05:52 PM
In message <2tt4b21fnnaovbhic7r62eajpd1c99r93o@4ax.com>, Joseph M. 
Newcomer <newcomer@flounder.com> 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@croctec.co.uk> wrote:
>
>>In message <78vsa2pvf963ot399thjp2f485jbl9path@4ax.com>, Joseph M.
>>Newcomer <newcomer@flounder.com> 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@croctec.co.uk> 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@flounder.com
>>>Web: http://www.flounder.com
>>>MVP Tips: http://www.flounder.com/mvp_tips.htm
>Joseph M. Newcomer [MVP]
>email: newcomer@flounder.com
>Web: http://www.flounder.com
>MVP Tips: http://www.flounder.com/mvp_tips.htm

-- 
Fenster
0
fenster (60)
7/11/2006 6:21:46 AM
OK, "always"?  I have become somewhat expert on taking non-functioning CSocket-based code
and rewriting it to CAsyncSocket code.  The code is always delivered to me with a long
list of problems, all of which are attributable to using synchronous sockets.  When I
rewrite it, the problems go away.  The code requires major reorganization because of the
fundamentally flawed assumption of synchronous communication.  The Good News is I make
lots of money doing this; the Bad News is I'm tired of doing it.

PostMessage is FIFO.  However, there are a couple issues that you might need to be
concerned with.

The key one is "Message queue flooding".  As long as there is a PostMessage message in the
queue, neither timer messages nor paint messages will be generated--they are only
generated when the queue is actually empty.  So you can block timers and painting
indefinitely if you have a lot of PostMessage messages in the queue.  ANother problem is
queue overflow.  The PostMessage queue has a limited finite size, and if you fill it up,
it will start discarding messages, thus not only undoing the good of TCP/IP, but usually
generating storage leaks (unless you check every PostMessage call).  Finally, you get the
problem of delays in the GUI.  I had this happen in a real app.  The nominal bandwidth was
very low, so I just used PostMessage.  But then he turned on "debug mode", and the
embedded processor started flooding us with messages!  I was scrolling messages by at a
ferocious rate when he said "OK, enough of this" and clicked the checkbox to turn off
"debug mode".  A couple minutes later the state of the check box changed and the messages
stopped flowing.  The mouse click was delayed behind the mass of PostMessage messages.

I have a solution that addresses all three of these problems; see my essay on my MVP Tips
site on using I/O Completion Ports as a queuing mechanism.  You do need to add what might
be otherwise a completely gratuitous SetTimer so the OnIdle doesn't block indefinitely.
					joe

On Tue, 11 Jul 2006 07:21:46 +0100, Fenster <fenster@croctec.co.uk> wrote:

>In message <2tt4b21fnnaovbhic7r62eajpd1c99r93o@4ax.com>, Joseph M. 
>Newcomer <newcomer@flounder.com> 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@croctec.co.uk> wrote:
>>
>>>In message <78vsa2pvf963ot399thjp2f485jbl9path@4ax.com>, Joseph M.
>>>Newcomer <newcomer@flounder.com> 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@croctec.co.uk> 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@flounder.com
>>>>Web: http://www.flounder.com
>>>>MVP Tips: http://www.flounder.com/mvp_tips.htm
>>Joseph M. Newcomer [MVP]
>>email: newcomer@flounder.com
>>Web: http://www.flounder.com
>>MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15972)
7/11/2006 12:54:32 PM
Reply:

Similar Artilces:

Backup question
I've moved to a new pc and for some reason I thought that when you backed up, a new file was created. Am I right? At the moment, it's just backing up to the backup file. So I've just just my working file and my backup file. Please could you clarify this? Thanks again. In microsoft.public.money, abc wrote: >I've moved to a new pc and for some reason I thought that when you >backed up, a new file was created. Am I right? At the moment, it's >just backing up to the backup file. So I've just just my working file >and my backup file. P...

Outlook Send/receive asks for Smart card.
Using W7 with Office 2003. Send and receive worked great to get to ATT but then I set -up Remote Desktop Connection to get to my office TS Gateway with a smart card. Now every time I do Send and Receive on Outlook, a pop-up window tells me to insert smart card. How do I get it to stop? Even willing to stop using connection to office but I can't figure out how to remove the smart card configuration. ...

Received Fax call but no pages were recived
Hi, I have a problem receiving Fax in UM Exchange. This is the error: Source: MSExchange Unified Messaging Event ID: 1028 UMCore The fax call from "25202637" for "faxtrisan" at number "810" was received but no pages were received. The fax call was 70.7392844 seconds long. The fax call was received from UM IP gateway "172.16.20.5". Someone have any idea ? ...

Question about Xml Schemas "qualified" and "unqualified"
In the textbook, there is a sentence that "Default XML namespaces(xmlns="...") helps a lot, but can also create problems, as a side effect of the rules for automatic qualification. How to understand "automatic qualification" here? Could you please give me an example? Secondly, unless otherwise specified, a schema prescribes that loal elements and attributes must be "unqualified". What does "unqualified" mean? Could you please giv eme an example? Finnaly, could you please tell me what's purpose of using these two things? Thanks a lot! ...

a question and a question
What is the correct name of the type of selection box used in "customizing Word", for example.... you select a word or operation from a list on the left pane and move it over to the right pane. Is there a template to build one of these? thanx You will have to explain more in detail what you are trying to do. -- Stefan Blom Microsoft Word MVP "cliffordjf" <cliffordjf@discussions.microsoft.com> wrote in message news:9856CCA7-8A8E-440C-A0D4-76EE4FA644E2@microsoft.com... > What is the correct name of the type of selection box used in "c...

Question about Paste Special
Hi, I have a problem sometimes with the paste special options when goin from one excel workbook to another. For example, sometimes when I cop data from one workbook and then paste special into another, I get th options that include: All, formulas, values, formats, has the option t transpose the data and paste link among other options. And the sometimes I try and paste data to another workbook and I end up th paste special options: Bitmap Image Object, picture, bitmap, and I als lose the ability to paste link. Well you can do it, but it puts it i as an object. What I want is the first past...

IE8 privacy question
I am running XP-Pro SP3 and considering upgrading from IE7 to IE8. I have read all the feature and benefit articles from MS, but have one question that remains unanswered. In IE8 there is mention of being able to restore previously viewed websites or something to that effect. I think this is on a drop down menu somewhere. 1) Does In-private viewing prevent this? 2) Does manually deleting your complete browsing history clear this? 3) Is there a registry entry that can prevent this action? 4) Is there a group policy change that can prevent this action? In essence for privacy pur...

IF AND question
Hi there, I need a function that can provide one of three answers: 1 2 1 1... 3 3 4 4... ? ? ? ?... If A1 = 1 and A2=3, answer 106; but if A1=1 and A2 = 4, answer 104; but if A1=2, regardless of A2, answer 95. The next function for column B is the same, except the answer is dependent on the value delivered from the column A function. E.g. A3 + 6 or A3 +4 or A3-5 etc. Any help would be most appreciated. -- ***** Many thanks Gamq Use the below formula for your first query. =IF(A1="","",IF(A1=2,95,IF(AND(A1=1,A2=3),106,IF(AND(A1=1,A2=4),104)))) ...

Microsoft Query question
I am trying to use Microsoft Query to get data from my SQL 2000 databases. The problem is that I have a few columns with names that conflict with keywords (like Identity). (Yes. I kow that keywords should be avoided but it is done and cannot be changed.) This is causing a keyword syntax error within the Query application. Oddly enough, even if I do not select the column the error still appears. And when you look at all the columns available, the keyword named column shows up in boldface. When I am doing queries in other programs I put square ("[ ]") brackets around column and table...

Question
Why did the chicken cross the road? -- Dr. Stephen Hopkins, MD "Dr. Stephen Hopkins, MD" <DrStephenHopkinsMD@discussions.microsoft.com> wrote in message news:B8434E21-DDA3-44D7-B39B-CD5A8C33A7BD@microsoft.com... > Why did the chicken cross the road? > -- > Dr. Stephen Hopkins, MD To collect her email, why else? Dr? You should be ashamed to put such a title on an idiotic off topic post !! -- Regards Steve. MS-MVP. MAIL. [DTS] UK. http://www.getsafeonline.org/ mac;1266180 Wrote: > "Dr. Stephen Hopkins, MD" <DrSte...

Cannot Receive Email with XP Pro and Outlook 2003
The subject line says it all, I can send email out with any of my three email accounts cannot receive email through my major email account which worked fine with Outlook 2002. Please help before I have to resort back to Outlook 2002. Try creating a new mail profile and then reset your account settings. --� Milly Staples [MVP - Outlook] Post all replies to the group to keep the discussion intact. Due to the SWEN virus, all mail sent to my personal account will be deleted without reading. After searching google.groups.com and finding no answer, bill asked: | The subject line says it ...

How do I get Outlook to receive my Cox.net email?
I have entered the pop3 and smtp addresses in Microsoft office 2003 Outlook according to the microsoft intructions for cox.net. I am able to send email but any incoming mail is still going to the Cox site, not to Outlook. "SusiB" <SusiB@discussions.microsoft.com> wrote in message news:67B45144-3C1E-4AC3-A3C1-5C33CAB11D8E@microsoft.com... >I have entered the pop3 and smtp addresses in Microsoft office 2003 Outlook > according to the microsoft intructions for cox.net. I am able to send > email > but any incoming mail is still going to the Cox site, not to Outlook...

OWA Question #16
Hello All: Quick Question regarding OWA. We are about to finalize migration from 5.5 to 2003. We have an existing web presence already in DNS a www.mydomain.com. and running on existing web servers. With 5.5 natrually, to access OWA, it was www.mydomain.com/exchange. This will not be possible now since OWA runs off of the Exchange server instead of relying on our web server under 5.5. What's the easiest way to overcome this. Thanks If you can afford the extra license, you'll probably want to run a front-end server so no one is connecting directly to the Exchange database s...

Text Box Question
Greetings, I have been using Visio for years, however, something has happened and I can't figure out how to undo it. Basically up until today when I added a text box and entered text, the text went horizontal as it was typed. Today when I add a text box and enter text, the text goes vertical. How do I get back to the old behavior? TIA using text container shape adjusting tool (text block tool), make the text container shape wider horizontally. Have you used Asian text font recently?...check help for "vertical text" "Ray Batig" wrote: > Greetings, > &g...

401K questions
I just started a 401K at work and I'm wondering how to deal with it in Money. I've got my paycheck split into different categories currently and now I have to put the 401K amount into a category as well. I didn't see one specifically for this. What do other people use? Should I start using the 401K Manager? I haven't gone through it yet I'm just wondering if it works well and how much benefit I'll get from it. Thanks in advance! Mike You will want to create an investment account for the 401(k) and TRANSFER your contributions from your checking account to the...

VBA//Oracle Interfacing Question
All, I have been able to correct to my database but I have one question question: Within objSession I want to list all available tables and all available views. How exactly is this done? thank you. Set objSession = CreateObject("OracleInProcServer.XOraSession") Set objDatabase = objSession.OpenDatabase("", "User/Pass", 0) On Nov 16, 12:05=A0pm, jason <jason.mell...@gmail.com> wrote: > All, > > I have been able to correct to my database but I have one question > question: > > Within objSession I want to list all avail...

If / Then Question
How would I do this: IF A1="N" then I need A2 and A3 to="N/A -- pkniven ----------------------------------------------------------------------- pknivens's Profile: http://www.excelforum.com/member.php?action=getinfo&userid=2767 View this thread: http://www.excelforum.com/showthread.php?threadid=47531 pknivens Wrote: > How would I do this: > > IF A1="N" then I need A2 and A3 to="N/A" Hi pknivens In A2 and A3 use this formula > =IF(A1="N","N/A",""), this will return blank if A1 is not N, if you want it...

ROWCOUNT question
Hi All, The below is a UDF that returns the ROWCOUNT for a table. I need to know that value for WHILE loop. How do I take the Returned value from the UDF and load it intio a variable in the SP where it was called from? Or maybe there is another way. ALTER FUNCTION [dbo].[RecCount] ( @TableName CHAR(15) ) RETURNS TABLE AS RETURN ( SELECT Rows FROM sysindexes WHERE id = OBJECT_ID(@TableName) AND indid < 2 ) Thanks, Eric Eric S (xxx_noSpam@Hotmail.com) writes: > The below is a UDF that returns the ROWCOUNT for a table. I need to know > that va...

Exmerge Question #7
When I run Exmerge on a mailbox on my 2003 server to export to a PST, it will delete all emails after the copy. I thought EXmerge would "copy" not delete. is this the default? If so how can I just have it do a copy out to the PST and leave the mailbox alone. thanks Rick in "options", make sure "archive data to target store" is not selected on the "Import procedure" tab... -- Susan Conkey [MVP] "Rick" <drummer10980@gmail.com> wrote in message news:1165509540.777142.38260@16g2000cwy.googlegroups.com... > When I run Exmerge on ...

question about "delete"
I have a pointer: MyWindowClass *p = NULL; p = new MyClass(...); .... delete p; After delete p, does p equal NULL(it is in C++ standard?)? How to decide if p has been deleted? The reason I asked this question is that in my project, there are many code/files use the pointer which I need to determine is it is deleted? Can I use: if(p != NULL) delete p; I guess somewhere p has been deleted, but p still not NULL(possible?), the above code might cause problem. Hi Kathy, I typically just set p to NULL when I delete it: delete p; p = NULL; Then you can check it in other places and ...

More combining companies questions
We too have acquired another company and need to look at all of our options concerning what to do with email. We run Exchange 2003, they run Exchange 2000. What is the best way to combine the two so we can share GAL, free-busy info, etc.? No decisions have been made as far as what we are going to do with their AD. We could of course change their MX record to point to our server, update our RUS, etc., but what if we want to keep an Exchange server at their site? What has to be done to join their server to our Exchange org? If you want sync both GAL,pls check this http://www.microso...

Collecting mail from multiple accounts
Currently I'm collecting mail from 3 seperate POP accounts. Is there any way to set Outlook 2003 up so that 1 account is set to receive mail every 5 minutes or so, and the other 2 accounts are only set up to receive mail every 12 hours? Thanks in advance. Regards, Sebastian Sebastian Kinnaird schrieb am 12/3/2004: > Currently I'm collecting mail from 3 seperate POP accounts. Is there > any way to set Outlook 2003 up so that 1 account is set to receive > mail every 5 minutes or so, and the other 2 accounts are only set up > to receive mail every 12 hours? > &...

switchboard question 12-26-07
Is there a way to put the names of different switchboard pages on the switchboard form? If you put one name on a switchboard page (in form design view), the same name appears on all the switchboard pages. I understand why this happens, but what if I want the user to be able to know which switchboard s/he is on? Thanks. PS the same thing happens if I go into form design view and put in control tip text. It puts the same text for the same-numbered menu item on two different switchboard pages. "Debbie S." wrote: > Is there a way to put the names of different switchboard ...

Some Questions about Outlook
1. what's the max size of attachment for sending email? 2. newMail notifitor: when there is a new mail, can the tary be changed to other until i check the mail? can it work with hotmail? 3. is there any function likes "To Do List"; calendar require time setting? 4. configure file backup; can i back up all of my setting? -- Me, Who I am On Sun, 7 May 2006 22:17:01 -0700, Dotku <lwjct@hotmail.com> wrote: >1. what's the max size of attachment for sending email? That would depend on your mail server/ISP. >2. newMail notifitor: when there is a new mail, can the ...

Simple CRM 3.0 Questions
- If an account is no longer active, what's the process to make it inactive? - Can a lead have multiple contacts, with one acting as the primary contact? - When I create a new lead, what the 'Topic' field usually used for? - When creating a lead, on the Details Page, how can I add entries into the 'Industry' and 'Lead Source' drop down lists? - Will CRM track all e-mails associated with a lead? How do I ensure this? - How do I promote a Lead to an Opportunity to an Account? - What's the real definition of an Opportunity? It seems so grey compared to...