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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
| Вернуться в корень Архива
|