Re: Why it can not work after I delete breakpoint.(attach the CSocketFile object to a CArchive)
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Fri, 29 Aug 2008 19:40:45 -0400
On Fri, 29 Aug 2008 22:23:56 GMT, "jmarc" <jmarc@xxxxxxxxxxxxxxxxxxxxx> wrote:
Despite any breakpoints in or out. This is****
hard to develop socket implementation
with the use of breakpoints... Like Joseph
said, timings are wrong...
My own code do the following way.. and
work very well.
void CMyOwnSocket::OnReceive(int nErrorCode)
{
// At least, check if something goes wrong with sub system..
if(nErrorCode == WSAENETDOWN)
{
// Up to you to behave on this..
}
// I do the process I need before calling the CSocket::OnReceive
method..
static BYTE localbuffer[10000];
NEVER declare a local static variable like this. It means you cannot have more than one
connection at a time! There is no reason this needs to exist, ever, for any imaginable
reason. Allocate a buffer in the class as a class member, and using CByteArray,
CArray<BYTE>, or std::vector<BYTE> makes far more sense than a static-sized buffer. But
generally assume that writing a local static variable is a programming error, and in the
incredibly rare once-a-decade situations where you need one, you will know it. This is
absolutely NOT one of those situations. It is best to forget you ever heard of the
concept of declaring static variables inside functions (the only time it seems to make
sense is if the declaration is preceded by the word 'const', which means it is not a
"variable" but a "named constant" (or named constant table)).
This code is really dangerous and should not be used.
****
int lgtoreceive = 5000; // or some calculation to****
know how many bytes to receive..
If the message coming down doesn't either implicitly or explicitly give you the number of
bytes to receive, you probably need to redesign your protocol. So choosing a random
number like the above could best be written as
int Igtoreceive = rand();
and be as valid. Which is what is happening anyway. You can assume the number of bytes
received is a random value which will differ on each receive call.
Take a look at my discussion about a simple network packet protocol on my MVP Tips site,
in my rewrite of the KB article on multithreaded sockets.
http://www.flounder.com/kb192570.htm
****
int lgreceive = Receive(&localbuffer, lgtoreceive); // Acquire the****
data..
// Up to you the way to handle the received data..
// .. at last, call the base class implementation... This is a way MSDN
suggest to do.. somewhere
You will receive from 1 to Igtoreceive bytes. Then you will have to deal with how you are
going to deal with the rest of the bytes. This is one of the most common errors in socket
programming, the expectation that data is received all at once. Data is received in
pieces of arbitrary length that usually bear zero correlation to the size of the
information that was sent. If I send 8192 bytes, I will get require between 1 and n
Receive operations to get the data, where n is unknown, unpredictable, and changes from
second to second so that no two 8192-byte packets will be received in the same way.
The fact that the "breakpoint" changes the behavior means that the OP is harboring some
delusion that there is the slightest correspondence between what is sent and what is
received, which is not true. The slightest change in timing will produce different
results, which means the code is wrong.
At the very minimum you need some kind of finite-state-machine reader which knows how to
assemble data blocks out of an incoming stream of data. This means the stream has to
encode the packet information in some way, and the number of ways this can be done is
fairly large: all packets are n bytes; packets that start with the letter 'A' are 22
bytes, with 'B' are 74 bytes, etc.; each packet starts with a 16-bit or 32-bit length
count of the number of data bytes; and on and on. But ultimately, you have to assume that
you are processing a stream of data, and it is the responsibility of the receiver to
assemble this data in a meaninful fashion as it comes in as a series of Receive
operations. (Note that if, to determine the size, you have to read more than one byte,
then you have to assume that you cannot read all the bytes in a single Receive operation;
my code encodes the length in 32 bits, and assumes that any given Receive will split one
of these length descriptions in the middle, which is what you have to expect).
This is why I asked for more information.
The above code may or may not work, but can only work for a single connection (I might
support several dozen concurrent connections), and the handwave about how to handle the
data is, unfortunately, the key part the OP probably needs.
****
****
CSocket::OnReceive(nErrorCode)
}
.. But there are other ways to handle sockets...
Many of which work. And work with multiple connections.
joe
****
Joseph M. Newcomer [MVP]
jmarc...
"zjs" <makefriend8@xxxxxxxxxxx> wrote in message
news:uZHBlePCJHA.4176@xxxxxxxxxxxxxxxxxxxxxxx
class CChatSocket : public CSocket
{
...
}
void CChatSocket::OnReceive(int nErrorCode)
{
CSocket::OnReceive(nErrorCode);//Here I insert a breakpoint,
m_pDoc->ProcessPendingRead();
}
It works well if I insert a breakpoint int the CHATTER (Client). but If I
delete that breakpoint, OnReceive function can not receive anything.(of
course CHATSRVR have the breakpoint too.the onlye changing is breakpoint)
the source code is in MSDN (CHATTER and CHATSRVR)
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Prev by Date: Re: Why it can not work after I delete breakpoint.(attach the CSocketFile object to a CArchive)
- Next by Date: Re: ? O-ishT: Designing an About Box
- Previous by thread: Re: Why it can not work after I delete breakpoint.(attach the CSocketFile object to a CArchive)
- Next by thread: Excel Programming: SetItem and SetValue Does not Work
- Index(es):
Relevant Pages
|