Author Topic: Waiting for a UDP Packet in Your Sample Code  (Read 2391 times)

Ciaraldi

  • Newbie
  • *
  • Posts: 4
Waiting for a UDP Packet in Your Sample Code
« on: May 18, 2011, 08:21:32 am »
I have been coding in C and C++ for many years, but mostly on Unix / Linux systems.
I am working now on a project that must be done in Visual C++ 2010, so I went looking on the Web for some sample code to start from. I found your "Sample UDP Client / Server Application"
      http://www.softwareandfinance.com/Visual_CPP/UDP_Client_Server.html
and it works great so far (thanks!), but I have two related questions:

1) The client sends a UDP packet containing text to the server, then waits for the reply. I would like instead to have the client be able to do something else while waiting. So I spawned a thread using a C function which has a loop in it that has the recvfrom() function inside the loop; it receives the packet, processes it, sleeps, and waits for the next packet. So far so good. But to make the reply appear on the screen I needed to pass the data back to the dialog window. So when I spawned the thread I passed it "this", which should be a pointer to the dialog object. The thread stores this pointer as a local variable, then uses that pointer to invoke a member function of the dialog that puts the text into the window and then calls UpdateData(FALSE). When I run this in Debug mode I get an ASSERT failure which says that the program cannot find the handle. If I click Ignore, it continues and does in fact display the text in the reply window. Of course, I do not want to ignore ASSERTS, so can anyone tell me what I am doing wrong?
Code snippets are at the end of this message.

2) The server doesn't seem to have this problem. The original has a function f() which looks like this:

static void f(void *p)
{
    ServerDlg *pDlg = reinterpret_cast<ServerDlg*>(p);
    pDlg->ProcessClientRequest(); // This receives the packet and processes it.
}

To me it looks like this function is somehow being called whenever a packet comes in, but I don't know why. I looked through the code and the headers and could not find a function prototype for it. I also could not find where it was being called from, or anything to indicate that it was being passed to the framework as some sort of event handler. Can someone enlighten me? Thanks!

-----------------------------------------------------
My client code looks like this:
In initialization:
   DWORD receiveThreadId;
   HANDLE rcvHandle = CreateThread(NULL, 0, receiveThread, this, 0, &receiveThreadId);

And here is the thread function:

DWORD WINAPI receiveThread (LPVOID lpdwThreadParam) {
   OryxClientDlg *dialogThread = (OryxClientDlg *) lpdwThreadParam;
   while(true) {
      dialogThread->receiveAndProcessMessage();
      Sleep(RECEIVE_INTERVAL);
   }
   return 0;
}

And the mmeber function:


int OryxClientDlg::receiveAndProcessMessage() {
   int result;
   char rbuf[MAX_MESSAGE_LENGTH];
   int len;

   len = sizeof(SOCKADDR_IN);

   // Should add a select() here.
   result = recvfrom(s, (char*) rbuf, MAX_MESSAGE_LENGTH, 0, (SOCKADDR*)&serveraddr, &len);
   if (result > 0) {
      processMessage(rbuf, result); // The UpdateData(FALSE) call is inside here.      
   }
   return 0;
}


kathir

  • Administrator
  • Sr. Member
  • *****
  • Posts: 283
Re: Waiting for a UDP Packet in Your Sample Code
« Reply #1 on: May 18, 2011, 10:45:22 am »
Here is the solution for your problem. Note: It would work fine in release mode.

To fix this problem in debug mode, do the following:

The place where you are calling UpdateData(FALSE), in your sample client code, it is processmessage. Do not call the UpdateData(FALSE), instead post a message pDlg->PostMessage(WM_USER + 1);

ON_MESSAGE(WM_USER + 1, UpdateDisplay)

LRESULT CSocketTestClientDlg::UpdateDisplay(WPARAM, LPARAM)
{
    UpdateData(FALSE);
    return 0;
}

The underlying problem with your code is, you are trying to access the window properties through another thread which does not own its object. By using PostMessage, you are giving the control back to main thread which can handle updatedata.

I have attached the updated sample code which does the work for you. I have tested it debug mode and it is working fine. You will not get the ASSERT. please use the updated files: SocketTestClientDlg.cpp and SocketTestClientDlg.h

Ciaraldi

  • Newbie
  • *
  • Posts: 4
Re: Waiting for a UDP Packet in Your Sample Code
« Reply #2 on: May 18, 2011, 04:28:01 pm »
Thanks very much -- your fix worked perfectly! Hurray!

Do you have any insight on my second question, how and why the function f() gets called?

Thanks again.

kathir

  • Administrator
  • Sr. Member
  • *****
  • Posts: 283
Re: Waiting for a UDP Packet in Your Sample Code
« Reply #3 on: May 19, 2011, 08:24:14 am »
Thanks very much -- your fix worked perfectly! Hurray!

Do you have any insight on my second question, how and why the function f() gets called?

Thanks again.

With in OnTimer function, I am creating a thread and passing the function f as pointer for callback. Look at the following code:

        if (FD_ISSET(m_serversocket, &fds))
        {

            m_bRefershData = false;

            HANDLE h = (HANDLE) ::_beginthread(f, 0, (void*) this);

        }


Ciaraldi

  • Newbie
  • *
  • Posts: 4
Re: Waiting for a UDP Packet in Your Sample Code
« Reply #4 on: May 19, 2011, 02:10:54 pm »
Ah, I see it now. I had done a global search for "f" but must have missed it before. Thanks again.

It looks to me like you are spawning a new thread every time a message comes in, which exits after that message has been processed. I am wondering why you did it that way, rather than a single thread which loops.

 I should say here that I have done a lot of multi-threaded programming in Java and in C on Unix / Linux systems, so I know that there are many ways to handle this situation. I was just wondering why you did it this way, and if it is related to how things are done in Visual C++.

kathir

  • Administrator
  • Sr. Member
  • *****
  • Posts: 283
Re: Waiting for a UDP Packet in Your Sample Code
« Reply #5 on: May 19, 2011, 02:19:27 pm »
Ah, I see it now. I had done a global search for "f" but must have missed it before. Thanks again.

It looks to me like you are spawning a new thread every time a message comes in, which exits after that message has been processed. I am wondering why you did it that way, rather than a single thread which loops.

 I should say here that I have done a lot of multi-threaded programming in Java and in C on Unix / Linux systems, so I know that there are many ways to handle this situation. I was just wondering why you did it this way, and if it is related to how things are done in Visual C++.

In this case, it does not require multithreading. I intentionally did it in this way so demonstrate multithreaded programming along with socket communication. It is for educative purpose only.

Ciaraldi

  • Newbie
  • *
  • Posts: 4
Re: Waiting for a UDP Packet in Your Sample Code
« Reply #6 on: June 13, 2011, 05:57:37 am »
Thanks for all your help.

My students put in many long hours and it paid off. Our team took first place at the NASA competition in Houston two weeks ago.
      http://www.telegram.com/article/20110527/NEWS/110529690/1116
Your sample code was vital to getting our code running in Visual Studio on Windows 7. Thanks again!

 


Disclaimer: This web site is for educational and informational purposes only. Click here to read the Disclaimer.
Content copyright 2010-2014. Kathiresan. All rights reserved.
This page is using SMF version 2.0.1