From: bernd on
Hi,

I`m trying to get a working socket example using MFC.... at the moment
I`m not able to receive any kind of packets...

That`s what I`m doing step by step:

1) installing a thread:

m_pClientThread =
(CUdpClientThread*)AfxBeginThread(RUNTIME_CLASS(CUdpClientThread),
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

m_pClientThread->SetTarget(AfxGetApp()->m_pMainWnd);
m_pClientThread->SetServerName(server);
m_pClientThread->SetPort(portnumber);
m_pClientThread->ResumeThread();

2) init socket
BOOL CUdpClientThread::InitInstance()
{
if(!CUdpSocketThread::InitInstance())
return FALSE;

if(!m_socket.Create(m_port, SOCK_DGRAM))
{ /* failed */
DWORD err = ::GetLastError();
ASSERT(target != NULL);
if(target != NULL)
target->PostMessage(UWM_NETWORK_ERROR, (WPARAM)err,
(LPARAM)::GetCurrentThreadId());
return FALSE;
} /* failed */

/* ******* */
LPCTSTR Data;
char buffer[20]= {10,10,101,10,10,10,10,10,10,10,10,10,10,10,10};
m_socket.SendTo(&buffer[0], strlen(&buffer[0]), m_port,
"2.255.255.255", 0);

return TRUE;
}

When I add the SendTo method to this function: the data will be
transmitted and after that the software will call the OnReceive
method....

Here are the class references:
class CUdpClientThread : public CUdpSocketThread
class CUdpSocketThread : public CWinThread
class UdpConnectSoc : public CAsyncSocket

And that`s the small OnReceive method - only for testing

void UdpConnectSoc::OnReceive(int nErrorCode)
{
if(nErrorCode != ERROR_SUCCESS)
{ /* had error */
AbortConnection(nErrorCode);
return;
} /* had error */



char buff[200];
int bytes_read = Receive(buff, 200);
buff[bytes_read] = 0; //terminate the string

}


Maybe someone of you will see some errors or have some information to
get a working example. I also tested some examples from microsoft
(http://support.microsoft.com/kb/185728/EN-US/) but these are also not
working... if I set this one up this app as server and port-nbr 5000 -
> the programm will also not receive any message (the firewall is not
active)....

best regards
Bernd
From: Joseph M. Newcomer on
See below...
On Fri, 21 May 2010 08:12:39 -0700 (PDT), bernd <bernd.schuster12(a)googlemail.com> wrote:

>Hi,
>
>I`m trying to get a working socket example using MFC.... at the moment
>I`m not able to receive any kind of packets...
>
>That`s what I`m doing step by step:
>
>1) installing a thread:
>
>m_pClientThread =
>(CUdpClientThread*)AfxBeginThread(RUNTIME_CLASS(CUdpClientThread),
>THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
>
>m_pClientThread->SetTarget(AfxGetApp()->m_pMainWnd);
>m_pClientThread->SetServerName(server);
>m_pClientThread->SetPort(portnumber);
> m_pClientThread->ResumeThread();
>
>2) init socket
>BOOL CUdpClientThread::InitInstance()
>{
>if(!CUdpSocketThread::InitInstance())
> return FALSE;
>
>if(!m_socket.Create(m_port, SOCK_DGRAM))
> { /* failed */
> DWORD err = ::GetLastError();
> ASSERT(target != NULL);
> if(target != NULL)
> target->PostMessage(UWM_NETWORK_ERROR, (WPARAM)err,
>(LPARAM)::GetCurrentThreadId());
> return FALSE;
> } /* failed */
>
>/* ******* */
>LPCTSTR Data;
>char buffer[20]= {10,10,101,10,10,10,10,10,10,10,10,10,10,10,10};
****
This string is erroneous. You are apply strlen to it, but it does not contain an embedded
\0 character at the end! And there is NO REASON EVER to put a bound in, like [20]. Just
declare it as

char buffer[] = {10,10,101,10,10,10,10,10,10,10,10,10,10,10,10, 0};

Because strlen is nonsensical, and you have no idea what it is returning, there is no
expectation the SendTo would work at all, but you failed to check its return code to see
if it succeeded, so you should not be surprised if nothing was received. You actually
have NO IDEA if ANYTHING was sent!

Note that UDP as a protcol sucks. Because this is UDP, the sending machine is NOT
OBLIGED to send it, and the receiving machine is NOT OBLIGED to accept it at all! So
failures should be common. You should expect that a UDP SendTo will fail. But it is more
likely to succeed if its parameters make sense, and you are going to know for sure if you
check the return code from the SendTo.

Also, the code suggests that you are using CSocket instead of CAsyncSocket, always a Bad
Idea.
****
>m_socket.SendTo(&buffer[0], strlen(&buffer[0]), m_port,
>"2.255.255.255", 0);
>
>return TRUE;
****
Why are you returning TRUE when you have no idea if this worked?
****
>}
>
>When I add the SendTo method to this function: the data will be
>transmitted and after that the software will call the OnReceive
>method....
****
All that SendTo guarantees is that the network stack will receive a SUGGESTION that it
MIGHT send data. And, as stated, there is no obligation on either side to deal with it.
One of the many reasons UDP is almost always a poor choice for real work.
****
>
>Here are the class references:
>class CUdpClientThread : public CUdpSocketThread
>class CUdpSocketThread : public CWinThread
>class UdpConnectSoc : public CAsyncSocket

****
But what type is the varible m_socket?
****
>
>And that`s the small OnReceive method - only for testing
>
>void UdpConnectSoc::OnReceive(int nErrorCode)
>{
>if(nErrorCode != ERROR_SUCCESS)
> { /* had error */
> AbortConnection(nErrorCode);
> return;
>} /* had error */
>
>
>
>char buff[200];
>int bytes_read = Receive(buff, 200);
>buff[bytes_read] = 0; //terminate the string
****
There is no guarantee this would EVER be called, because you are using UDP. And why do
you think the entire message will fit in 200 bytes? UDP should expect 512 bytes. Note
that if you ever got a message > 200 bytes, the rest of the message is lost forever; it
will not come in on the next Receive. And if you ever SEND a message > 512 bytes, it can
be silently truncated by anyone between your app and the receiving app, including your
network stack, the receiver's network stack, or any router along the way. And you will
never know.

It is good that you add a 0 byte to the end of the buffer, but in this case, you are doing
nothing with it; how are you going to process this? There's huge potential for error when
you add processing code.

There's a reason we don't use UDP, and that is that it is fundamentally unreliable, and
that is a technical term in networking. It means you will never know if data is actually
sent, and you will never know if the receiver has received it. Or multiple copies of it.
Or receives several packets out-of-order. If I send three packets, A, B and C, the
receiver might get them in the sequence ABC, or ABBC, or ACB, or AC, or as many variations
of the letters A, B and C as you can imagine, in any order, including zero or multiple
instances. Also, UDP does not embody any flow management, which means you can "saturate"
your LAN or every router between the sender and receiver, and consequently create even
more opportunities to lose or duplicate packets!

UDP looks easy. In fact, it is a complete and total disaster if you are concerned with
reliable and robust communication!
joe
****
>
>}
>
>
>Maybe someone of you will see some errors or have some information to
>get a working example. I also tested some examples from microsoft
>(http://support.microsoft.com/kb/185728/EN-US/) but these are also not
>working... if I set this one up this app as server and port-nbr 5000 -
>> the programm will also not receive any message (the firewall is not
>active)....
****
5000 is not a good choice of port number because it is in the reserved range.
joe
****
>
>best regards
>Bernd
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm