Solved

WSAAsyncSelect( ) usage?

Posted on 1997-11-21
14
752 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
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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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
Redirect page to logout only when page is idle to 1 mins (or whenever) 1 58
Mixed results 10 90
Windows 10 Scheduled Tasks 11 98
SSRS troubles 4 68
This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
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…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

809 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