15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CAsyncSocket @ Receive a Datagram

Charlie Jursch -- cjursch@pacbell.net
Wednesday, November 06, 1996

Environment: NT4.0 and VC++ 4.1

I am trying to get a socket communication to work between two computers on
a LAN.  I have had varying success to date.  Here is a brief description of
the environment.  I have a driver running under NT Server 4.0 that sends a
datagram every 10 secs to an application running under NT Workstation 4.0.
The datagram is being sent correctly to the correct port as I can capture
the message with Network Monitor.  On the receiving side I have a
CAsyncSocket created in a worker thread with the following code (the start
event is triggered by a TIMER in the main thread):

    m_pCL = (CALLLISTINFO*) pParam;
    CPSIAsyncSocket sock;
    UINT nPort = 1500;
    BOOL result = TRUE;

    BOOL rtn = sock.Create (nPort
                           ,SOCK_DGRAM);

    if  (rtn == FALSE)
    {
       int err = sock.GetLastError();
       result = ErrorCheck(err);
    }

    if (result == FALSE)
    {
       CString msg = "socket not created";
       AfxMessageBox (msg);
       return 100;
    }

    m_pCL->m_aCallList.SetSize(100);

  // passes a pointer to the common data struct that has the windows     //
handles in to return messages to 
  // depending upon what type of datagram is received
    sock.SetReturnHandles(m_pCL);


   //  enter the thread processing loop
    while (TRUE)
    {
   //  wait for the start event to fire
       if(WaitForSingleObject(m_pCL->m_hEventStart, INFINITE)
                         != WAIT_OBJECT_0)
          break;

   //  check for a kill thread event before doing any processing
       if(WaitForSingleObject(m_pCL->m_hEventKillThread, 0)
                         == WAIT_OBJECT_0)
          break;

       void* p1 = sock.GetBufferPtr();

       int rtn = sock.ReceiveFrom(p1
                                 ,NETWORK_DATAGRAM_BUFFER_SIZE
                                 ,m_pCL->m_csSocketAddress
                                 ,m_pCL->m_nSocketPort);

       if (rtn == SOCKET_ERROR)
       {
          int err = sock.GetLastError();
          result = ErrorCheck(err);
       }
       else if (rtn > 0)
       {
          sock.ReceiveMessage(); // process the message in the buffer
// TRACE1 ("buffer size returned is %d \n", rtn);
          }
       }
    }

    return 0;
}

I receive messages just fine until I open a view in the main thread.  Then
I start getting a WSAEFAULT error on every ReceiveFrom until I exit the
application.  I have also tried the following code with an override in the
CPSIAsyncSocket for OnReceive and I never get to the OnReceive funtions:

    m_pCL = (CALLLISTINFO*) pParam;
    CPSIAsyncSocket sock;
    UINT nPort = 1500;
    BOOL result = TRUE;

    BOOL rtn = sock.Create (nPort
                           ,SOCK_DGRAM);

    if  (rtn == FALSE)
    {
       int err = sock.GetLastError();
       result = ErrorCheck(err);
    }

    rtn = sock.AsyncSelect(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);

    if (rtn == SOCKET_ERROR)
    {
       int err = sock.GetLastError();
       result = ErrorCheck(err);
    }

    if (result == FALSE)
    {
       CString msg = "socket not created";
       AfxMessageBox (msg);
       return 100;
    }

    m_pCL->m_aCallList.SetSize(100);
    m_pCL->m_bMsgRcvd = FALSE;

    sock.SetReturnHandles(m_pCL);

   //  enter the thread processing loop
    while (TRUE)
    {
   //  wait for the start event to fire
       if(WaitForSingleObject(m_pCL->m_hEventStart, INFINITE)
                         != WAIT_OBJECT_0)
          break;

   //  check for a kill thread event before doing any processing
       if(WaitForSingleObject(m_pCL->m_hEventKillThread, 0)
                         == WAIT_OBJECT_0)
          break;

       void* p1 = sock.GetBufferPtr();

       int rtn = sock.ReceiveFrom(p1
                                 ,NETWORK_DATAGRAM_BUFFER_SIZE
                                 ,m_pCL->m_csSocketAddress
                                 ,m_pCL->m_nSocketPort);

       if (rtn == SOCKET_ERROR)
       {
          int err = sock.GetLastError();
          result = ErrorCheck(err);
       }

       SetEvent(m_pCL->m_hEventDone);
    }

    return 0;
}

I have run Spy++ on the SocketSink window and I never get any messages to
trigger the callback to OnReceive.

Any assistance is greatly appreciated.

Charlie
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Charlie Jursch              "Be kind to your web-footed
Patotech Software, Inc.      friends for a duck may be
1-800-PATOTECH               somebody's mother."
mailto: cjursch@pacbell.net    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



Les -- Les.Hill@FMR.Com
Friday, November 08, 1996

Charlie,

>From your description of your first code snippet, you would be better off   
    

just using the raw WinSock calls corresponding to your
current use of CAsyncSocket.

In the second code snippet, your worker thread should have a message pump   
    

running in order for CAsyncSocket to work.  Why? Because
CAsyncSocket is using WSAAsyncSelect() to generate windows messages to a   
    

hidden window, which ends up calling your overridden functions such as
OnReceive().  In terms of which of the two approaches to use, I think
that using a UI thread to handle the socket is the easiest way to go,
although your termination conditions will need to be reworked (perhaps by   
    

using thread messages instead of events).

Les Hill
leh@cybercom.net

 ----------Original message follows

Environment: NT4.0 and VC++ 4.1

I am trying to get a socket communication to work between two computers   
    

on
a LAN.  I have had varying success to date.  Here is a brief description   
    

of
the environment.  I have a driver running under NT Server 4.0 that sends   
    

a
datagram every 10 secs to an application running under NT Workstation
4.0.
The datagram is being sent correctly to the correct port as I can capture
the message with Network Monitor.  On the receiving side I have a
CAsyncSocket created in a worker thread with the following code (the
start
event is triggered by a TIMER in the main thread):

    m_pCL = (CALLLISTINFO*) pParam;
    CPSIAsyncSocket sock;
    UINT nPort = 1500;
    BOOL result = TRUE;

    BOOL rtn = sock.Create (nPort
                           ,SOCK_DGRAM);

    if  (rtn == FALSE)
    {
       int err = sock.GetLastError();
       result = ErrorCheck(err);
    }

    if (result == FALSE)
    {
       CString msg = "socket not created";
       AfxMessageBox (msg);
       return 100;
    }

    m_pCL->m_aCallList.SetSize(100);

  // passes a pointer to the common data struct that has the windows
    //
handles in to return messages to
  // depending upon what type of datagram is received
    sock.SetReturnHandles(m_pCL);


   //  enter the thread processing loop
    while (TRUE)
    {
   //  wait for the start event to fire
       if(WaitForSingleObject(m_pCL->m_hEventStart, INFINITE)
                         != WAIT_OBJECT_0)
          break;

   //  check for a kill thread event before doing any processing
       if(WaitForSingleObject(m_pCL->m_hEventKillThread, 0)
                         == WAIT_OBJECT_0)
          break;

       void* p1 = sock.GetBufferPtr();

       int rtn = sock.ReceiveFrom(p1
                                 ,NETWORK_DATAGRAM_BUFFER_SIZE
                                 ,m_pCL->m_csSocketAddress
                                 ,m_pCL->m_nSocketPort);

       if (rtn == SOCKET_ERROR)
       {
          int err = sock.GetLastError();
          result = ErrorCheck(err);
       }
       else if (rtn > 0)
       {
          sock.ReceiveMessage(); // process the message in the buffer
// TRACE1 ("buffer size returned is %d \n", rtn);
          }
       }
    }

    return 0;
}

I receive messages just fine until I open a view in the main thread.
 Then
I start getting a WSAEFAULT error on every ReceiveFrom until I exit the
application.  I have also tried the following code with an override in
the
CPSIAsyncSocket for OnReceive and I never get to the OnReceive funtions:

    m_pCL = (CALLLISTINFO*) pParam;
    CPSIAsyncSocket sock;
    UINT nPort = 1500;
    BOOL result = TRUE;

    BOOL rtn = sock.Create (nPort
                           ,SOCK_DGRAM);

    if  (rtn == FALSE)
    {
       int err = sock.GetLastError();
       result = ErrorCheck(err);
    }

    rtn = sock.AsyncSelect(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);

    if (rtn == SOCKET_ERROR)
    {
       int err = sock.GetLastError();
       result = ErrorCheck(err);
    }

    if (result == FALSE)
    {
       CString msg = "socket not created";
       AfxMessageBox (msg);
       return 100;
    }

    m_pCL->m_aCallList.SetSize(100);
    m_pCL->m_bMsgRcvd = FALSE;

    sock.SetReturnHandles(m_pCL);

   //  enter the thread processing loop
    while (TRUE)
    {
   //  wait for the start event to fire
       if(WaitForSingleObject(m_pCL->m_hEventStart, INFINITE)
                         != WAIT_OBJECT_0)
          break;

   //  check for a kill thread event before doing any processing
       if(WaitForSingleObject(m_pCL->m_hEventKillThread, 0)
                         == WAIT_OBJECT_0)
          break;

       void* p1 = sock.GetBufferPtr();

       int rtn = sock.ReceiveFrom(p1
                                 ,NETWORK_DATAGRAM_BUFFER_SIZE
                                 ,m_pCL->m_csSocketAddress
                                 ,m_pCL->m_nSocketPort);

       if (rtn == SOCKET_ERROR)
       {
          int err = sock.GetLastError();
          result = ErrorCheck(err);
       }

       SetEvent(m_pCL->m_hEventDone);
    }

    return 0;
}

I have run Spy++ on the SocketSink window and I never get any messages to
trigger the callback to OnReceive.

Any assistance is greatly appreciated.

Charlie
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Charlie Jursch              "Be kind to your web-footed
Patotech Software, Inc.      friends for a duck may be
1-800-PATOTECH               somebody's mother."
mailto: cjursch@pacbell.net
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




| Вернуться в корень Архива |