Looking for information on MFC TCP Communication  
Author Message
robald





PostPosted: Tue Aug 16 10:55:13 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication We have roughly 6 software programs that run in tandum with each other
that currnetly use UDP to transmit information (Images, various little
packets, etc) between each program. I'm developing a new application
that is pumping more data through and we've decided to give TCP a shot.

I'm personally new to Network communication and TCP, I know the basics,
but nothing in-depth. I'm looking to develop a generic stand-alone
class with input and output queues that will act as an interface for
each program. I think this will be the best way to go, but welcome any
other suggestions from those with more experience.

Can someone point me to a location where I can get an intro to socket
communication with MFC?
The sending / receiving will be done in seperate threads as queue data
arrives. I've read that CAsyncSocket has issues with threading. Does
anyone know if this is still the case?

Thanks in advance for the help,
Josh McFarlane

Visual Studio375  
 
 
Tom





PostPosted: Tue Aug 16 10:55:13 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication http://www.cppdoc.com/example/mfc/classdoc/MFC/CSocket.html
http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/mfc/

Tom


"Josh McFarlane" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
> We have roughly 6 software programs that run in tandum with each other
> that currnetly use UDP to transmit information (Images, various little
> packets, etc) between each program. I'm developing a new application
> that is pumping more data through and we've decided to give TCP a shot.
>
> I'm personally new to Network communication and TCP, I know the basics,
> but nothing in-depth. I'm looking to develop a generic stand-alone
> class with input and output queues that will act as an interface for
> each program. I think this will be the best way to go, but welcome any
> other suggestions from those with more experience.
>
> Can someone point me to a location where I can get an intro to socket
> communication with MFC?
> The sending / receiving will be done in seperate threads as queue data
> arrives. I've read that CAsyncSocket has issues with threading. Does
> anyone know if this is still the case?
>
> Thanks in advance for the help,
> Josh McFarlane
>


 
 
Josh





PostPosted: Tue Aug 16 14:50:06 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Tom Serface wrote:
> http://www.cppdoc.com/example/mfc/classdoc/MFC/CSocket.html
> http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/mfc/

How about transmitting the actual data?

For example, I'll have to send a basic header package with the
information on the image size, and other readings. Do I just read the
set amount of bytes for the header structure, and assume that they are
in the correct order?

The whole reading and receiving theory I need a little bit more reading
up on. I know that I'll need a basic header structure, with the bytes
to follow for the package and perhaps an ID or type of package (Image,
data, etc), so they can be decoded on the other end, but I do not know
how to prep them for network transport (I figure I can treat them as
char buffers but do not know the proper way to do it).

Thanks,
Josh

 
 
Tom





PostPosted: Tue Aug 16 16:40:11 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication The data is guaranteed (as much as possible) to be intact when received. So,
what you send should be what you receive. It should be a simple FIFO
buffer. Try some of the demo at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_windows_sockets.3a_.stream_sockets.asp

Tom

"Josh McFarlane" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
> Tom Serface wrote:
>> http://www.cppdoc.com/example/mfc/classdoc/MFC/CSocket.html
>> http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/mfc/
>
> How about transmitting the actual data?
>
> For example, I'll have to send a basic header package with the
> information on the image size, and other readings. Do I just read the
> set amount of bytes for the header structure, and assume that they are
> in the correct order?
>
> The whole reading and receiving theory I need a little bit more reading
> up on. I know that I'll need a basic header structure, with the bytes
> to follow for the package and perhaps an ID or type of package (Image,
> data, etc), so they can be decoded on the other end, but I do not know
> how to prep them for network transport (I figure I can treat them as
> char buffers but do not know the proper way to do it).
>
> Thanks,
> Josh
>


 
 
David





PostPosted: Tue Aug 16 20:48:51 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication The receiver may also have to insure that it has received all of the
data intended for a packet. For instance, sending a 10,000 byte message
under TCP does not necessarily mean that it will all come at once.
A simple read loop is generally enough to handle the concept of reading
a message.

That is the only "mistake" I often see newcomers to TCP make. They
will read part of a transmission and then start operating on the
entire message presuming that it was received as asked. Just because
a receiver asks for a certain amount of information does not gaurantee
that it will be delivered immediately. CAsyncSocket helps this problem
to some degree. Still you will need a little bookkeeping to insure that
what was sent is what was received.

David

On Tue, 16 Aug 2005 21:40:11 UTC, "Tom Serface" <EMail@HideDomain.com> wrote:

> The data is guaranteed (as much as possible) to be intact when received. So,
> what you send should be what you receive. It should be a simple FIFO
> buffer. Try some of the demo at:
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_windows_sockets.3a_.stream_sockets.asp
>
> Tom
>
> "Josh McFarlane" <EMail@HideDomain.com> wrote in message
> news:EMail@HideDomain.com...
> > Tom Serface wrote:
> >> http://www.cppdoc.com/example/mfc/classdoc/MFC/CSocket.html
> >> http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/mfc/
> >
> > How about transmitting the actual data?
> >
> > For example, I'll have to send a basic header package with the
> > information on the image size, and other readings. Do I just read the
> > set amount of bytes for the header structure, and assume that they are
> > in the correct order?
> >
> > The whole reading and receiving theory I need a little bit more reading
> > up on. I know that I'll need a basic header structure, with the bytes
> > to follow for the package and perhaps an ID or type of package (Image,
> > data, etc), so they can be decoded on the other end, but I do not know
> > how to prep them for network transport (I figure I can treat them as
> > char buffers but do not know the proper way to do it).
> >
> > Thanks,
> > Josh
> >
>
>


 
 
Scott





PostPosted: Tue Aug 16 21:53:38 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Josh McFarlane wrote:
> We have roughly 6 software programs that run in tandum with each other
> that currnetly use UDP to transmit information (Images, various little
> packets, etc) between each program. I'm developing a new application
> that is pumping more data through and we've decided to give TCP a shot.
>
> I'm personally new to Network communication and TCP, I know the basics,
> but nothing in-depth. I'm looking to develop a generic stand-alone
> class with input and output queues that will act as an interface for
> each program. I think this will be the best way to go, but welcome any
> other suggestions from those with more experience.
>
> Can someone point me to a location where I can get an intro to socket
> communication with MFC?
> The sending / receiving will be done in seperate threads as queue data
> arrives. I've read that CAsyncSocket has issues with threading. Does
> anyone know if this is still the case?
>
> Thanks in advance for the help,
> Josh McFarlane
>

CAsyncSocket provides a non-blocking socket. This means that Send and
Receive will always return quickly. (But perhaps with a WOULDBLOCK
error code.) This makes it possible in most applications to efficiently
do both sending and receiving in the same thread. If you must do them
in separate threads you cannot use a single CAsyncSocket. Your options
then would be the winsock API (especially WSAEventSelect) or using two
separate CAsyncSocket sockets, one in each thread.

The basics of using CAsyncSocket in MFC threads are illustrated by the
MFCAsync sample code, downloadable from MSDN.

--
Scott McPhillips [VC++ MVP]

 
 
Josh





PostPosted: Wed Aug 17 09:20:03 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication David wrote:
> A simple read loop is generally enough to handle the concept of reading
> a message.

So I send 2 sets of data from the client, say header then package, the
following logic should work properly on the receiving end:

Read until buffer >= sizeof(HEADER)
Analyze Header
Read until Buffer >= sizeof(Package specified in header)

Then I can deal with the package properly?

What happens if I read more bytes than the data I'm looking for?
Wouldn't that impact the next read operation on the data by shorting it
of that many bytes?

Thanks,
Josh

 
 
Scott





PostPosted: Wed Aug 17 17:20:10 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Josh McFarlane wrote:
> David wrote:
>
>>A simple read loop is generally enough to handle the concept of reading
>>a message.
>
>
> So I send 2 sets of data from the client, say header then package, the
> following logic should work properly on the receiving end:
>
> Read until buffer >= sizeof(HEADER)
> Analyze Header
> Read until Buffer >= sizeof(Package specified in header)
>
> Then I can deal with the package properly?
>
> What happens if I read more bytes than the data I'm looking for?
> Wouldn't that impact the next read operation on the data by shorting it
> of that many bytes?
>
> Thanks,
> Josh
>

For best efficiency your buffer management code can read all it can get
every time it calls Receive/recv. If bytes remain in the buffer from a
previous read then pass the pointer to the first free byte, and pass the
byte count remaining in your buffer. After parsing out whatever whole
messages you have in the buffer, move any remaining bytes down to the
start of the buffer.

--
Scott McPhillips [VC++ MVP]

 
 
Joseph





PostPosted: Wed Aug 17 22:59:57 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Generally, UDP is untrustworthy and you should not use it for any serious application. So
TCP really is your only safe choice.

Pretty much everything you just described is in CAsyncSocket.

Note that to use the MFC socket classes the separate threads must be UI threads, although
there is rarely a need to use separate threads. Note that separate threads must not
manipulate any windows owned by the GUI thread. Other than the obvious of using a UI
thread instead of a worker thread, providing appropriate synchronization for shared
objects, and not touching the GUI, there are no "thread issues". Synchronization and the
GUI interactions are fundamental to ALL threading and not unique to sockets, and the UI
thread is documented, so it isn't really an "issue".
joe

On 16 Aug 2005 08:46:21 -0700, "Josh McFarlane" <EMail@HideDomain.com> wrote:

>We have roughly 6 software programs that run in tandum with each other
>that currnetly use UDP to transmit information (Images, various little
>packets, etc) between each program. I'm developing a new application
>that is pumping more data through and we've decided to give TCP a shot.
>
>I'm personally new to Network communication and TCP, I know the basics,
>but nothing in-depth. I'm looking to develop a generic stand-alone
>class with input and output queues that will act as an interface for
>each program. I think this will be the best way to go, but welcome any
>other suggestions from those with more experience.
>
>Can someone point me to a location where I can get an intro to socket
>communication with MFC?
>The sending / receiving will be done in seperate threads as queue data
>arrives. I've read that CAsyncSocket has issues with threading. Does
>anyone know if this is still the case?
>
>Thanks in advance for the help,
>Josh McFarlane
Joseph M. Newcomer [MVP]
email: EMail@HideDomain.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
 
 
Josh





PostPosted: Thu Aug 18 09:22:50 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Joseph M. Newcomer wrote:
> Note that to use the MFC socket classes the separate threads must be UI threads, although
> there is rarely a need to use separate threads. Note that separate threads must not
> manipulate any windows owned by the GUI thread. Other than the obvious of using a UI
> thread instead of a worker thread, providing appropriate synchronization for shared
> objects, and not touching the GUI, there are no "thread issues". Synchronization and the
> GUI interactions are fundamental to ALL threading and not unique to sockets, and the UI
> thread is documented, so it isn't really an "issue".
> joe
Got the 'don't touch the GUI' part down. One part I don't understand is
why it needs a UI thread.

Do the notifications of received data and etc require a queue in order
to properly route to the CAsyncSocket? If so, is there anything I need
to do beyond just the using the UI thread to ensure that the
CAsyncSocket gets it's notifications? (Adding message handlers?)

The reason I thought about seperate threads was that I was just going
to have the sending thread block when there was no information to send
(using a constant loop with a queue system). Since the UI thread would
have a handler and a non-blocking socket, I can definately try to
consolidate them into one.


Ok, one more quick question. I'm going to have to have a buffer for
each image before I transmit it across the network. Normally, I'd just
allocate the buffer , but this may be allocating / deleting alot of
space for just a short period of use. Do you think that it might be
worth looking into using pools of Image Buffer objects rather than
new/delete-ing them on the spot? Allocation tends to be a big part of
my resource chokes, and using the pool method might help alliviate it,
but never used it before. Granted, I'm going to try it without and see
if it's necessary first, but I was just looking for any comments if you
guys have used it before.

Thanks again,
Josh McFarlane

 
 
Josh





PostPosted: Thu Aug 18 14:43:17 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Wow, I've learned so much over the past few days... TCP seems so
complicated but once you get the ideas behind it down, you can make
alot of progres.

This question is about CAsyncSockets:

For the OnReceive handler of my object:
Should I call Receive in a loop until the return of it is less than the
maximum buffer size?

Should I call a handler function for the raw received data within
OnReceive, or post a message to the thread to notify it of new data?

After calling the base CAsyncSocket::OnReceive, any new data will cause
a new notification message correct?

(Also, rare case, but what happens when BufferSize is exactly equal to
the bytes queued? IE first call Receive == MaxBuffer, but the next call
Receive == 0, which would indicate the connection closed. This is more
out of curiosity than anything.)

 
 
Scott





PostPosted: Thu Aug 18 18:10:13 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Josh McFarlane wrote:
> Wow, I've learned so much over the past few days... TCP seems so
> complicated but once you get the ideas behind it down, you can make
> alot of progres.
>
> This question is about CAsyncSockets:
>
> For the OnReceive handler of my object:
> Should I call Receive in a loop until the return of it is less than the
> maximum buffer size?

You should call Receive one time in OnReceive. As a side effect that
one call requests another OnReceive when more data is available.

>
> Should I call a handler function for the raw received data within
> OnReceive, or post a message to the thread to notify it of new data?

A handler function is fine. Do not call anything that pumps messages
(such as MessageBox) in OnReceive. (Could cause reentry.) If you
really had a need to do a message box then posting a message to yourself
would be a better approach.

> After calling the base CAsyncSocket::OnReceive, any new data will cause
> a new notification message correct?

The base CAsyncSocket::OnReceive does nothing. Calling Receive will
cause a new notification message, if and when more data is available.

>
> (Also, rare case, but what happens when BufferSize is exactly equal to
> the bytes queued? IE first call Receive == MaxBuffer, but the next call
> Receive == 0, which would indicate the connection closed. This is more
> out of curiosity than anything.)

Calling receive when no data is available produces an error, and
GetLastError returns the WSAE_WOULDBLOCK code. I.e., it tells you
there's no date right now.


--
Scott McPhillips [VC++ MVP]

 
 
Scott





PostPosted: Thu Aug 18 18:12:24 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Josh McFarlane wrote:
> Got the 'don't touch the GUI' part down. One part I don't understand is
> why it needs a UI thread.
>
> Do the notifications of received data and etc require a queue in order
> to properly route to the CAsyncSocket? If so, is there anything I need
> to do beyond just the using the UI thread to ensure that the
> CAsyncSocket gets it's notifications? (Adding message handlers?)

The socket notifications come in to the thread's message queue. So you
have to have a thread with a queue. CAsyncSocket contains the message
handlers. It turns the messages into calls to your virtual functions
like OnReceive.

--
Scott McPhillips [VC++ MVP]

 
 
Josh





PostPosted: Thu Aug 18 17:51:20 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Scott McPhillips [MVP] wrote:
> You should call Receive one time in OnReceive. As a side effect that
> one call requests another OnReceive when more data is available.

Is there a reason behind only calling Receive once per call?

When the package is in a state receiving it's size header, I only want
to receive 4 bytes to the buffer, then convert them to the length and
allocate the new buffer.

After this, I'd like to call receive again and pull out as much data as
I can from the buffer to be efficient (One pass vs two passes),
however, if there's a compelling reason to wait til the second pass,
I'm all ears and will follow that instead.

Thanks,
Josh McFarlane

 
 
David





PostPosted: Thu Aug 18 20:23:54 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Hi Josh,

On Wed, 17 Aug 2005 14:20:03 UTC, "Josh McFarlane" <EMail@HideDomain.com>
wrote:

> David wrote:
> > A simple read loop is generally enough to handle the concept of reading
> > a message.
>
> So I send 2 sets of data from the client, say header then package, the
> following logic should work properly on the receiving end:
>
> Read until buffer >= sizeof(HEADER)
> Analyze Header
> Read until Buffer >= sizeof(Package specified in header)
>
> Then I can deal with the package properly?

That can work well for the first package.

> What happens if I read more bytes than the data I'm looking for?
> Wouldn't that impact the next read operation on the data by shorting it
> of that many bytes?

The second "read until" loop should only ask for the amount of data
that the HEADER indicates the Package will contain. This way the next
read data could be a new HEADER.

There are many ways to organize and pass the data between the two
applications. (Header-Data)* is a good approach for many problems.
It does get into problems when you start reading the next Header or
Data and it isn't what you expected. Are you reading in the middle
of another message? Did the sender have a problem sending a message
and get confused? How would your application best get back in sync
with each other? When the content matters, it is best to provide
ways of detecting and correcting communication faults. Thus, the
first lesson is building one way communications that work and the
next lesson is making sure that there is ample feedback to keep
both applications speaking and understanding one another.

> Thanks,
> Josh

David
 
 
Joseph





PostPosted: Sat Aug 20 11:12:38 CDT 2005 Top

MFC >> Looking for information on MFC TCP Communication Note that there is no guarantee that if you ask for the 4-byte header that you will get 4
bytes. You have to assume that *every* read operation will give you a partial read, and
you have to do something like use a Finite State Machine to recognize if you have the
entire length before you can proceed.

I do this by having an enum type which represents what state I'm in, for example,
STATE_HEADER_0 - waiting for first byte of length
STATE_HEADER_1 - read 1 byte of length, need to read 3 more
STATE_HEADER_2 - read 2 bytes of length, need to read 2 more
STATE_HEADER_3 - read 3 bytes of length, need to read 1 more
STATE_DATA - read all 4 bytes of length, need to read data based on length

So the first thing you do is try to read 4 bytes of header starting at STATE_HEADER_0. If
you get all 4 byte, you proceed to STATE_DATA. If you get only 3 bytes, you proceed to
STATE_HEADER_3 and read only one additional byte, which will then put you in STATE_DATA.
And so on (I gave this as an example for my intro-to-networks-in-Java class a few years
ago, for people who were largely non-programmers, so it isn't all that hard).

You stay in STATE_DATA until you read all the data bytes, then reset to STATE_HEADER_0 and
start all over again. FSM models are really nice for handling this sort of problem.

I'm not sure what you mean by "two passes". There is no concept of "pass" here. You read
data until you run out of data, and if it is a partial header, you have no choice but to
wait for the next OnReceive event. It could take you two calls, or two hundred, depending
on your buffer size, and if it takes you 200, then it means that the data wasn't ready and
you needed to wait yet again. If this represents a split in the header, well, it is a
split in the header. That's life.

Remember that the cost of the calls is several orders of magnitude smaller than the cost
of a packet transmission, so your performance will be limited by network bandwidth, not
by the number of calls to Receive you make.
joe

On 18 Aug 2005 15:51:20 -0700, "Josh McFarlane" <EMail@HideDomain.com> wrote:

>Scott McPhillips [MVP] wrote:
>> You should call Receive one time in OnReceive. As a side effect that
>> one call requests another OnReceive when more data is available.
>
>Is there a reason behind only calling Receive once per call?
>
>When the package is in a state receiving it's size header, I only want
>to receive 4 bytes to the buffer, then convert them to the length and
>allocate the new buffer.
>
>After this, I'd like to call receive again and pull out as much data as
>I can from the buffer to be efficient (One pass vs two passes),
>however, if there's a compelling reason to wait til the second pass,
>I'm all ears and will follow that instead.
>
>Thanks,
>Josh McFarlane
Joseph M. Newcomer [MVP]
email: EMail@HideDomain.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm