Solved

WSAAsyncSelect( ) usage?

Posted on 1997-11-21
14
762 Views
Last Modified: 2013-12-03
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.
0
Comment
Question by:sherwingw
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
14 Comments
 

Author Comment

by:sherwingw
ID: 1408708
Edited text of question
0
 
LVL 3

Expert Comment

by:vinniew
ID: 1408709
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
 

Author Comment

by:sherwingw
ID: 1408710
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
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 

Author Comment

by:sherwingw
ID: 1408711
Adjusted points to 250
0
 

Author Comment

by:sherwingw
ID: 1408712
Adjusted points to 275
0
 

Author Comment

by:sherwingw
ID: 1408713
Adjusted points to 285
0
 

Author Comment

by:sherwingw
ID: 1408714
Adjusted points to 300
0
 

Author Comment

by:sherwingw
ID: 1408715
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
 
LVL 1

Expert Comment

by:ete
ID: 1408716
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
 

Author Comment

by:sherwingw
ID: 1408717
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
 
LVL 1

Expert Comment

by:ete
ID: 1408718
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
 

Author Comment

by:sherwingw
ID: 1408719
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
 
LVL 1

Accepted Solution

by:
richhxb earned 400 total points
ID: 1408720
This will be compiled successfully.

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


0
 

Author Comment

by:sherwingw
ID: 1408721
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

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Where can I find the FoxPro ODBC Download version 1.0 6 54
Event ID 10010 3 81
Post a good COM tutorial 1 73
Is IHttpActionResult a promise pattern? 2 82
This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question