We have a client server implementation using a CSocket derived class, a CSocketFile and two archives ( one for receiving, one for sending ) in the connection class. So far it seems to be pretty vanilla and right out of the book.
However, I get error messages while sending from the server to the client once in a while, totally unpredictable and not reproducable. The message itself is not spectacular. It says, roughly translated: "unknown error accessing an unknown file". The unknown file is the socket, so it basically says "sending failed".
PHP Code:
BOOL CSAZConnection::Send( const CSAZMessage* SazMsg )
{
LOG_ENTER( CSAZConnection::Send );
CSingleLock SingleLock( &m_SendMutex );
SingleLock.Lock();
if( ! IsOpen() )
{
LOG_DUMP( "Connection is not open" )
LOG_EXIT( CSAZConnection::Send );
return FALSE;
}
if( GetError() )
{
LOG_DUMP( "Connection had errors" )
LOG_EXIT( CSAZConnection::Send );
return FALSE;
}
LOG_DUMP_NUMERIC( SazMsg->mv_MessageType )
//
// Falls kein Socket existiert, kann keine Nachricht versandt werden
//
if( m_pSocket == NULL )
{
LOG_DUMP( "Socket is NULL" )
LOG_EXIT( CSAZConnection::Send );
return FALSE;
}
//
// Falls der Socket blockiert ist hier abbrechen
//
if( TimedOutWhileBlocking() )
{
LOG_EXIT( CSAZConnection::Send );
return FALSE;
}
//
// Jetzt die Nachricht senden und den
// temporären Buffer leeren
//
try
{
LOG_DUMP( "trying to stream into archive" )
(*m_pArchiveOut) << (*SazMsg);
LOG_DUMP( "flushing archive" )
m_pArchiveOut->Flush();
LOG_DUMP( "flushing done" )
OutputDebugString( "Message sent" );
//LOG_DUMP( SazMsg->ToDebugString() );
}
catch( CException *e )
{
SendErrorMessage( e,
_T("Error while sending Message [Type:[%u], Action:[%u]]: "),
SazMsg->mv_MessageType,
SazMsg->mv_Action );
LOG_EXIT( CSAZConnection::Send );
return FALSE;
}
catch(...)
{
SendErrorMessage( NULL,
_T("Error while sending Message [Type:[%u], Action:[%u]]: Unknown"),
SazMsg->mv_MessageType,
SazMsg->mv_Action );
LOG_EXIT( CSAZConnection::Send );
return FALSE;
}
//
// Sendung erfolgreich
//
LOG_EXIT( CSAZConnection::Send );
return TRUE;
}
This function produces the following log:
Code:
12/09/04 13:56:37 (0960DFA0) Enter: CSAZConnection::Send
12/09/04 13:56:37 (0960DFA0) 2010
12/09/04 13:56:37 (0960DFA0) Enter: CSAZConnection::TimedOutWhileBlocking
12/09/04 13:56:37 (0960DFA0) Exit: CSAZConnection::TimedOutWhileBlocking
12/09/04 13:56:37 (0960DFA0) trying to stream into archive
12/09/04 13:56:37 (0960DFA0) flushing archive
12/09/04 13:58:19 (0960DFA0) Enter: CSAZConnection::SendErrorMessage
12/09/04 13:58:19 (0960DFA0) Enter: CSAZConnection::SetError
12/09/04 13:58:19 (0960DFA0) Exit: CSAZConnection::SetError
12/09/04 13:58:19 (0960DFA0) Exit: CSAZConnection::SendErrorMessage
12/09/04 13:58:19 (0960DFA0) Exit: CSAZConnection::Send
Note the lines
->> LOG_DUMP( "trying to stream into archive" )
->> LOG_DUMP( "flushing archive" )
and the absence of
->> LOG_DUMP( "flushing done" )
plus the fact that the exception thrown explicitly states that an error occurred in the socket.
I'm stumped. I'd say that it's not in my hands anymore and it's a network i.e. Hardware error, but no other programms we use have problems ( or rather they have, but my boss doesn't want to see them ).
So is there anything I can do about this safe of writing my own winsock wrapper ( and have that fail if it's a network problem ) ?
I have found a lot of sites advising against using CSocket, but I have not yet heard a single fact why and what to use instead.