⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cworkersocket.cpp

📁 WINCE下的流媒体播放器服务端
💻 CPP
字号:
/*======================================================================== 
CWorkerSocket.cpp
Implement of Base Class
=========================================================================*/

#include "stdafx.h"
#include "CWorkerSocket.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////////////////////
CWorkerSocket::CWorkerSocket()
{
	m_hSocket      = NULL;
	m_bReceiving   = false;
	m_bSending     = false;

	// Initialize thread event
	m_hThrdFinish = ::CreateEvent( NULL,    // pointer to security attributes 
		    					   TRUE,      // flag for manual-reset event 
								   FALSE,     // flag for initial state 
								   NULL );     // pointer to event-object name
	m_hSendFinish = ::CreateEvent( NULL, 
	    						   TRUE, 
								   FALSE, 
								   NULL ); 
}

CWorkerSocket::~CWorkerSocket()
{
	// Close the socket
	Disconnect();

	// Release the thread event
	if ( m_hThrdFinish )
	{
		CloseHandle( m_hThrdFinish );
		m_hThrdFinish = NULL;
	}
	if ( m_hSendFinish )
	{
		CloseHandle( m_hSendFinish );
		m_hSendFinish = NULL;
	}
}

//Attach a connected sockt to this object
bool CWorkerSocket::Attach( SOCKET inSock )
{
	if ( m_hSocket == NULL )
	{
		m_hSocket = inSock;
		return true;
	}
	return false;
}

SOCKET CWorkerSocket::Detach( void )
{
	SOCKET hSock = m_hSocket;
	m_hSocket    = NULL;
	return hSock;
}

// Send data on connected sockets, blockingly
int CWorkerSocket::Send( char * inData, int inLen )
{
	if ( m_hSocket )
	{
		char * pData = inData; //new char[inLen];
		if ( !pData )
			return E_SOCKET_FAIL;

		TIMEVAL tm;
		fd_set wfds;
		FD_ZERO( &wfds );
		FD_SET( m_hSocket, &wfds );
		tm.tv_sec  = 1;
		tm.tv_usec = 0;
		// Make sure the current socket can write
		if ( select( 0, NULL, &wfds, NULL, &tm ) )
		{
			int nret   = 0;
			int nCount = inLen;
			do 
			{
				nret = send( m_hSocket, pData, nCount, 0 );
				if ( nret == SOCKET_ERROR )
				{
					return E_SOCKET_FAIL;
				}
				nCount -= nret;
				pData  += nret;
				if ( nCount > 0 )
				{ 
					Sleep( 20 );
				}
			} while ( nCount > 0 );
			return S_SOCKET_OK;
		}
		else
		{
			// The socket cannot write currently
			return E_SOCKET_NOT_READY;
		}
	}

	return E_SOCKET_FAIL;
}

int CWorkerSocket::Receive( char * outBuf, int inLen )
{
	if ( m_hSocket )
	{
		// Check socket for readability 
		TIMEVAL tv;
		tv.tv_sec  = 0;
		tv.tv_usec = 0;
		fd_set rfds;
		FD_ZERO( &rfds );
		FD_SET( m_hSocket, &rfds );
		if ( select( 1, &rfds, NULL, NULL,&tv ) )
		{
			int    nCount = inLen;
			int    lenret = 0;
			char * pBuf   = outBuf;
			do 
			{
				lenret = recv( m_hSocket, pBuf, nCount, 0 );
				if ( lenret == SOCKET_ERROR ) 
				{
					return E_SOCKET_FAIL;
				}
				else if ( lenret == 0 )
				{
					// Indicate the socket disconnected
					return E_SOCKET_CLOSE;
				}
				nCount -= lenret;
				pBuf   += lenret;
				if ( nCount > 0 )
				{ 
					Sleep(20);
				}
			} while (nCount > 0);
			return S_SOCKET_OK;
		}
		else
		{
			// The socket not ready to read
			return E_SOCKET_NOT_READY;
		}
	}
	return E_SOCKET_FAIL;
}

void CWorkerSocket::Disconnect( void )
{
	if ( m_hSocket )
	{
		// Terminate receiving and sending thread if necessary
		if ( m_bReceiving )
		{
			StopReceiving();
		}
		if ( m_bSending )
		{
			StopSending();
		}

		closesocket( m_hSocket );
		m_hSocket = NULL;
	}
}

// Connect to the remote socket
bool CWorkerSocket::Connect( char * inIpAddress, int inPort )
{
//	char bufOutput[MAX_PATH];
//	sprintf( bufOutput, TEXT( "connect, inPort = [%d]" ), inPort );
//	AfxMessageBox( bufOutput );

	Disconnect();
	// Create a new socket to connection
	m_hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    if ( m_hSocket == INVALID_SOCKET )
	{
		m_hSocket = NULL;
		return false;
	}	

	BOOL sopt = TRUE;
	setsockopt( m_hSocket, IPPROTO_TCP, TCP_NODELAY, ( char * )&sopt, sizeof( BOOL ) );
	setsockopt( m_hSocket, SOL_SOCKET, SO_DONTLINGER, ( char * )&sopt, sizeof( BOOL ) );

	// Resolve hostname
	DWORD  addr = inet_addr( inIpAddress );
	if( addr == INADDR_NONE ) 
	{
		struct hostent *he = gethostbyname( inIpAddress );
		if ( he == NULL ) 
		{
			closesocket( m_hSocket );
			m_hSocket = NULL;
			return false;
		}
		addr = *( DWORD * )( he->h_addr_list[ 0 ] );
	}
    
	// Create socket address
	SOCKADDR_IN   saddr;
	memset( &saddr, 0, sizeof( SOCKADDR_IN ) );
	saddr.sin_addr.S_un.S_addr = addr;
	saddr.sin_family           = AF_INET;
	saddr.sin_port             = htons( inPort );

	// Connect to the remote host
	DWORD dwError = 0;
	dwError = connect( m_hSocket, ( SOCKADDR * )&saddr, sizeof( SOCKADDR_IN ) );
	
	if( dwError == SOCKET_ERROR ) 
	{
//		dwError = WSAGetLastError();
//		sprintf( bufOutput, TEXT( "after connect, error code:[%ld]" ), dwError );
//		AfxMessageBox( bufOutput );

		closesocket( m_hSocket );
		m_hSocket = NULL;
		return false;
	}
    return true;
}

////////////////////////////////////////////////////////////////////////////
// Start a data receiving thread
bool CWorkerSocket::StartReceiving( void )
{
	if ( m_hSocket )
	{
		if ( m_bReceiving )
		{
			return true;
        }
		m_bReceiving = true;
		ResetEvent( m_hThrdFinish );
		// Make socket blocking safely
		u_long   nonBlock = FALSE;
		ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		AfxBeginThread( ( AFX_THREADPROC )CWorkerSocket::ReceivingThrd, this );
		return true;
	}
	return false;
}

bool CWorkerSocket::StopReceiving( void )
{
	if ( m_hSocket )
	{
		if ( !m_bReceiving )
		{
			return true;
		}
		m_bReceiving = false;
		// Make socket nonblocking to terminate receiving thread
		char pData[ sizeof( MSG_HEADER ) ];
		PMSG_HEADER pMsg = ( PMSG_HEADER ) pData;
		pMsg->nDataSize  = 0;
		pMsg->nMsgType   = RECV_EXIT_REQUEST;
		Send( pData, sizeof( MSG_HEADER ) );
	//	u_long   nonBlock = TRUE;
	//	ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		WaitForSingleObject(m_hThrdFinish, 2000);
		// Restore to blocking socket
	//	nonBlock = FALSE;
	//	ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		return true;
	}
	return false;
}

// Virtual method, receive loop
void CWorkerSocket::ReceivingLoop( void )
{
}

UINT CWorkerSocket::ReceivingThrd( void * pParam )
{
	CWorkerSocket * pSock = ( CWorkerSocket * ) pParam;
	if ( pSock != NULL )
	{
		pSock->ReceivingLoop();
	}

	SetEvent( pSock->m_hThrdFinish );
	return 1;
}

////////////////////////////////////////////////////////////////////////////
bool CWorkerSocket::StartSending( void )
{
	if ( m_hSocket )
	{
		if ( m_bSending )
		{
			return true;
		}
		m_bSending = true;
		ResetEvent(m_hSendFinish);
		// Make socket blocking safely
	//	u_long   nonBlock = FALSE;
	//	ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		AfxBeginThread( ( AFX_THREADPROC )CWorkerSocket::SendingThrd, this );
		return true;
	}
	return false;
}

bool CWorkerSocket::StopSending( void )
{	
	if ( m_hSocket )
	{
		if ( !m_bSending )
		{
			return true;
        }
		m_bSending = false;
		// Make socket nonblocking to terminate sending thread
	//	u_long   nonBlock = TRUE;
	//	ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		WaitForSingleObject(m_hSendFinish, 2000);
		// Restore to blocking socket
	//	nonBlock = FALSE;
	//	ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		return true;
	}
	return false;
}

// Virtual method: data-sending loop
void CWorkerSocket::SendingLoop( void )
{
}

UINT CWorkerSocket::SendingThrd( void * pParam )
{	
	CWorkerSocket * pSock = ( CWorkerSocket * ) pParam;
	if ( pSock != NULL )
	{
		pSock->SendingLoop();
	}

	SetEvent( pSock->m_hSendFinish );
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -