// BufferedSocket.cpp: implementation of the CBufferedSocket class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "BufferedSocket.h" ////////////////////////////////////////////////////////////////////// // 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, 0/*MSG_PARTIAL*/ ); if ( nb == SOCKET_ERROR ) { int err = this->GetLastError(); if ( err != WSAESHUTDOWN ) // shutdown by remote side ? TRACE("error Receive %d socket %d\n",this->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 ); if ( !empty ) { // TRACE("CBufferedSocket::OnSend Sending buffer %s\n",msg.c_str()); 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 = this->GetLastError(); switch ( err ){ case WSAEWOULDBLOCK: // si la file est pleine on sort en silence ! break; case WSAECONNABORTED: // broken pipe on sort en silence break; default: TRACE("CBufferedSocket::OnWakeup error %d Sending buffer %s \n",err,msg.c_str()); break; } break; } } } while ( !empty ); } void CBufferedSocket::OnConnect( int nErrorCode ) { connected = true; StartWriter(); // TRACE("CBufferedSocket::OnConnect buffer size %d\n",buf_out.size()); } 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", this->GetLastError()); // } }