WSAAsyncSelect( ) usage?

I have written an MFC application that needs to receive data from a telnet port.  I had previously placed recv calls in an endless loop in a global function.  It worked, but hogged CPU time.  I am now trying to get the same service working using WSAAsyncSelect( ).  I am calling the function from my CMainFrame::OnCreate but am not seeing my message being passed to the appropriate message handler
(ie. the message handler:
void CMainFrame::OnServerMessageWaiting(WPARAM wParam, LPARAM lParam)
is never called).  I think it is because I am not using the correct value for the second argument of WSAAsyncSelect( )

// Turn on Windows Message Notification of socket events
      WSAAsyncSelect( Socket_to_Server,
                        m_hWnd,  // <- WHAT SHOULD THIS BE?
                        ID_SERVER_MESSAGE_WAITING,
                        (FD_READ | FD_CLOSE));

Or maybe I am doing something else wrong.
sherwingwAsked:
Who is Participating?
 
richhxbConnect With a Mentor Commented:
This will be compiled successfully.

::WSAAsyncSelect
(
Socket_to_Server,
this->m_hWnd,
ID_SERVER_MESSAGE_WAITING,
(FD_READ | FD_CLOSE)
);


0
 
sherwingwAuthor Commented:
Edited text of question
0
 
vinniewCommented:
You're dealing with an extra layer of abstraction with the MFC stuff...

I would suggest adding a handler to the wndProc to get the messages instead.  Also, are you filtering the FD_READ and FD_CLOSE correctly?  I'd need to see the beginning of the On_server_message_waiting function to know for sure.  What I mean is that you have to look at both the lParam and wParam and I'm not sure that MFC isn't filtering it somewhere.

If you need more, post the code for that function.


0
[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

 
sherwingwAuthor Commented:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
     RECT Rect;
     LPCRECT lpRect = &Rect;
     Rect.top = 500;
     Rect.left = 500;
     Rect.bottom = 700;
     Rect.right = 700;
     first_select = 0;
     m_wndWindowPointer = this->m_hWnd;
     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
      return -1;
    .
    .
    .

     // Make the connection to the ADDS_Server
     Connect_to_ADDS_Server();
     return 0;
} // int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

BOOL CMainFrame::Connect_to_ADDS_Server()
{
      int status;
     char Server_Connection_Message[40];
      u_short Socket_Assigned_by_Server;
     SOCKET Server_Listening_Socket;
     SOCKADDR_IN Server_Listening_Socket_Address;
     SOCKADDR_IN Socket_Assigned_by_Server_Address;
     WSADATA WSAData;
      long ADDS_Server_Address;

     // First open socket
     if(WSAStartup(0x01, &WSAData))
     {
          Show_Error_Popup((const unsigned char *) "Cannot initialize
WinSock library");
     }

    Socket_Assigned_by_Server = 1;
     Socket_to_Server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if ( Socket_to_Server == 0)
     {
          Show_Error_Popup((const unsigned char *) "Unable to establish
connection to server");
          return(FALSE);
     }
     // Bind socket to the appropriate port
     ZeroMemory(&Socket_Assigned_by_Server_Address, sizeof(SOCKADDR_IN));
    Socket_Assigned_by_Server_Address.sin_family = AF_INET;
     Socket_Assigned_by_Server_Address.sin_port =
htons(Socket_Assigned_by_Server);
     Socket_Assigned_by_Server_Address.sin_addr.s_addr =
ADDS_Server_Address;
     // connect to assigned socket

     if ( (connect ( Socket_to_Server,
                             (LPSOCKADDR)&Socket_Assigned_by_Server_Address,
                             sizeof ( Socket_Assigned_by_Server_Address)
                                                                     )) ==
SOCKET_ERROR)
     {
          Show_Error_Popup ( (const unsigned char *) "Cannot connect to
Assigned Server Socket" );
          return(FALSE);
     }

     // Receive Server Connection Message;
     status = recv( Socket_to_Server, Server_Connection_Message, 32, 0 );
     Show_on_Client_Console((const unsigned char *)
Server_Connection_Message);

     // Turn on Windows Message Notification of socket events
     ::WSAAsyncSelect(   Socket_to_Server,
                                          AfxGetMainWnd()->GetSafeHwnd(),
                                          ID_SERVER_MESSAGE_WAITING,
                                          (FD_READ | FD_CLOSE));
     return(TRUE);
}

Message Map Entry

ON_MESSAGE(ID_SERVER_MESSAGE_WAITING, OnServerMessageWaiting)

...

void CMainFrame::OnServerMessageWaiting(WPARAM wParam, LPARAM lParam)
{
    // TODO: Add your command handler code here
     int status;
     char status_string[80];
     char * pstatus_string = status_string;

    if(WSAGETSELECTERROR(lParam)) // <=== BREAK POINT SET HERE!
     {
          // An error occurred
     }

     switch (WSAGETSELECTEVENT(lParam))  // <=== BREAK POINT SET HERE!
     {
        case FD_READ:
        status = recv( Socket_to_Server, (char *)
&Server_Status_Broadcast.ADDS_Mode, 5, 0 );
        .
        .
        .

0
 
sherwingwAuthor Commented:
Adjusted points to 250
0
 
sherwingwAuthor Commented:
Adjusted points to 275
0
 
sherwingwAuthor Commented:
Adjusted points to 285
0
 
sherwingwAuthor Commented:
Adjusted points to 300
0
 
sherwingwAuthor Commented:
vinniew:  Its not that I want to reject this answer, but I have not received any response to the code posting I sent in as you requested.  I am finding more and more, that VC++ and MFC are riddled with incompletely documented functions that make the job of a newbie totaly frustrating.  What I want is to detect incoming messages from a tcpip socket and then parse off these messages to do various things in the client, from changing indicators, to displaying Que-Lists.  I want the client to continue processing and to be able to send messages to the same socket, while I am waiting for server messages.  Any further help would be greatly appreciated.
0
 
eteCommented:
It seems that you may be handling the ID_SERVER_MESSAGE_WAITING in message loop of a wrong window. It depends on the type of your application. If it is an OLE-server, you would be handling it correctly, if not you have an error in your code.

If an OLE-server has an object that is in-place active inside a container, and this container is active, AfxGetMainWnd() returns a pointer to the frame window object that contains the in-place active document.

If there is no object that is in-place active within a container, or your application is not an OLE-server, this function simply returns the m_pMainWnd of your application object.

This means, that you should handle the ID_SERVER_MESSAGE_WAITING in window procedure of your applications main window, not of the frame window.

ETE


0
 
sherwingwAuthor Commented:
ete:
>This means, that you should handle the
>ID_SERVER_MESSAGE_WAITING in window procedure of your
>applications main window, not of the frame window

Please forgive me, but I am a neophyte at both Windows and MFC.
I think I understand what you are saying conceptually, but I do
not have a clue as to what the hWnd argument should be, and as
to where the handler should be either.  I thought that since the
primary purpose of this message handler is to receive tcp/ip
data that will be used to modify ToolBar settings, that all this
stuff would belong in MainFrame.  If this is not true, then I
have no idea where it should be, In the app? If so, how do I
maintain control of the ToolBars  (I know this is very telling
as to my Windows programming skill lack)

Thank you for your response,  I have to finish this project
before the end of the year.
0
 
eteCommented:
Okay. If you want to handle the messages in the frame window, change the window handle in WSAAsyncSelect() to point to the frame window. Following code should do.

::WSAAsyncSelect
(
Socket_to_Server,
this->hWnd,
ID_SERVER_MESSAGE_WAITING,
(FD_READ | FD_CLOSE)
);


0
 
sherwingwAuthor Commented:
This does not compile.

::WSAAsyncSelect
(
Socket_to_Server,
this->hWnd,
ID_SERVER_MESSAGE_WAITING,
(FD_READ | FD_CLOSE)
);

It throws the following compile error:

MainFrm.cpp
J:\ADDS-Server\NewJobReq\MainFrm.cpp(834) : error C2039: 'hWnd' : is not a member of 'CMainFrame'
0
 
sherwingwAuthor Commented:
Although this compiles, for some reason, I am still not receiving
the ID_SERVER_MESSAGE_WAITING  message.  Any further Ideas, NOTE:
I have posted the code previously, then added your suggested
change.

Thanks
0
All Courses

From novice to tech pro — start learning today.