// BufferedSocket.cpp: implementation of the CBufferedSocket class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "BufferedSocket.h" #ifdef _DEBUG #define DEBUG_NEW new(__FILE__, __LINE__) #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CBufferedSocket::CBufferedSocket() { separator = '\n'; ptr = buf; connected = false; InitializeCriticalSection( &m_CritSection ); } CBufferedSocket::~CBufferedSocket() { } void CBufferedSocket::Accept(CBufferedSocket& rConnectedSocket, SOCKADDR* lpSockAddr , int* lpSockAddrLen ) { CThreadedSocket::Accept(rConnectedSocket, lpSockAddr , lpSockAddrLen ); rConnectedSocket.connected = true; } void CBufferedSocket::OnReceive(int nErrorCode) { char *ptr_nl; long nb_to_read = 0; long nb; SOCKADDR addr; int len = sizeof( addr ); /* limitation taille buffer */ nb_to_read = MAX_BUFFER - ( ptr - buf ); if( nb_to_read == 0 ) { TRACE("Erreur message trop long sans LF\n"); ptr = buf; return; } nb = ReceiveFrom( ptr, nb_to_read, &addr, &len, MSG_PARTIAL ); if ( nb == SOCKET_ERROR ) { int err = GetLastError(); if ( err != WSAESHUTDOWN ) // shutdown by remote side ? TRACE("error Receive %d socket %d\n",GetLastError(),m_hSocket); Close(); return; } if ( nb == 0 ) // shutdown by remote side ? { Close(); return; } ptr += nb; ASSERT( ptr < (buf +sizeof( buf ))); *ptr = '\0'; ptr = buf; while( (ptr_nl = strchr( ptr, '\n' ))) { *ptr_nl = '\0'; //TRACE("message %s\n", ptr ); OnReceive( ptr ); ptr = ++ptr_nl; } if ( *ptr != '\0' ) { /* recopie ligne incomplete au debut du buffer */ strcpy( buf, ptr ); ptr = buf + strlen(buf); } else { ptr = buf; } } void CBufferedSocket::OnReceive( char *line ) { } void CBufferedSocket::SetSeparator( char sep ) { separator = sep; } void CBufferedSocket::OnSend( int nErrorCode ) { string msg; bool empty; // on essaye de garder la section critique a l'interieur de la boucle // pour permettre l'entrelacement avec la partie emetrice do { EnterCriticalSection( &m_CritSection ); empty = buf_out.empty(); if ( !empty ) msg = buf_out.front(); LeaveCriticalSection( &m_CritSection ); TRACE("CBufferedSocket::OnSend Sending buffer %s\n",msg.c_str()); if ( !empty ) { int lg = msg.length(); int sent = CThreadedSocket::Send( msg.c_str(), lg ); if ( sent == lg ) { // emission correcte on enleve le msg de la file EnterCriticalSection( &m_CritSection ); buf_out.pop_front(); LeaveCriticalSection( &m_CritSection ); } else { // erreur int err = GetLastError(); if ( err == WSAEWOULDBLOCK ) // si la file est pleine on sort en silence ! { } else TRACE("CBufferedSocket::OnWakeup error %d Sending buffer %s \n",err,msg); break; } } } while ( !empty ); } void CBufferedSocket::OnConnect( int nErrorCode ) { connected = true; StartWriter(); //TRACE("CBufferedSocket::OnConnect buffer empty %d\n",buf_out.IsEmpty()); } void CBufferedSocket::Send ( const char * data ) { //BOOL toBeSignaled; EnterCriticalSection( &m_CritSection ); //toBeSignaled = buf_out.IsEmpty() && connected; buf_out.push_back( string(data) ); LeaveCriticalSection( &m_CritSection ); //TRACE("CBufferedSocket::Send Adding buffer to send count %d\n",buf_out.size()); // if ( connected ) // { bool ok = SignalWriter(); if ( !ok ) TRACE( "CBufferedSocket::SignalWriter Error %d\n", ::GetLastError()); // } }