www.pudn.com > AVChat1.rar > CStreamSocket.cpp


//  
// CStreamSocket.cpp 
//  
 
/*-----------------------------------------------------*\ 
			HQ Tech, Make Technology Easy!        
 More information, please go to http://hqtech.nease.net. 
/*-----------------------------------------------------*/ 
 
#include "stdafx.h" 
#include  
#include "CStreamSocket.h" 
#include "CFilterNetReceiver.h" 
#include "GlobalDefs.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
////////////////////////////////////////////////////////////////////////////// 
CStreamSocket::CStreamSocket() 
{ 
	mSocket      = INVALID_SOCKET; 
	mIsConnected = FALSE; 
 
	mIsReceiving = FALSE; 
	mIsSending   = FALSE; 
	mRcvThread   = NULL; 
	mSndThread   = NULL; 
 
	mOwnerFilter = NULL; 
} 
 
CStreamSocket::~CStreamSocket() 
{ 
	Detach(); 
	StopSending(); 
	StopReceiving(); 
} 
 
void CStreamSocket::SetOwnerFilter(CFilterNetReceiver * inFilter) 
{ 
	mOwnerFilter = inFilter; 
} 
 
BOOL CStreamSocket::Attach(SOCKET inSocket) 
{ 
	if (mSocket != INVALID_SOCKET) 
	{ 
		return FALSE; 
	} 
 
	mSocket      = inSocket; 
	mIsConnected = TRUE; 
	return TRUE; 
} 
 
void CStreamSocket::Detach(void) 
{ 
	if (mSocket != INVALID_SOCKET) 
	{ 
		closesocket(mSocket); 
		mSocket = INVALID_SOCKET; 
		mIsConnected = FALSE; 
	} 
} 
 
SOCKET CStreamSocket::GetSocket(void) 
{ 
	SOCKET ret   = mSocket; 
	mSocket      = INVALID_SOCKET; 
	mIsConnected = FALSE; 
	return ret;	 
} 
 
BOOL CStreamSocket::ConnectTo(DWORD inTargetIP, WORD inPort) 
{ 
	if (mIsConnected) 
	{ 
		return TRUE; 
	} 
 
	mSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
	if (mSocket != INVALID_SOCKET) 
	{ 
		BOOL sopt = TRUE; 
		setsockopt(mSocket, IPPROTO_TCP, TCP_NODELAY,  
			(char *)&sopt, sizeof(BOOL)); 
		setsockopt(mSocket, SOL_SOCKET, SO_DONTLINGER,  
			(char *)&sopt, sizeof(BOOL)); 
 
		SOCKADDR_IN   saddr; 
		memset(&saddr, 0, sizeof(SOCKADDR_IN)); 
		saddr.sin_addr.S_un.S_addr = htonl(inTargetIP); 
		saddr.sin_family           = AF_INET; 
		saddr.sin_port             = htons((WORD)inPort); 
		if (connect(mSocket, (SOCKADDR *)&saddr, sizeof(SOCKADDR_IN)) != 0)  
		{ 
			Detach(); 
			return FALSE; 
		} 
		mIsConnected = TRUE; 
		return TRUE; 
	} 
	return FALSE; 
} 
 
BOOL CStreamSocket::StartReceiving(void) 
{ 
	if (mSocket != INVALID_SOCKET) 
	{ 
		if (mIsReceiving) 
		{ 
			return TRUE; 
		} 
 
		DWORD threadID = 0; 
		mRcvThread = CreateThread(NULL, 0, ReceivingThrd,  
			this, 0, &threadID); 
		return (mRcvThread != NULL); 
	} 
	return FALSE; 
} 
 
void CStreamSocket::StopReceiving(void) 
{ 
	if (mIsReceiving) 
	{ 
		Detach(); 
		if (mRcvThread != NULL)  
		{ 
            WaitForSingleObject(mRcvThread, INFINITE); 
			mRcvThread = NULL; 
		} 
	} 
} 
 
BOOL CStreamSocket::StartSending(void) 
{ 
	if (mSocket != INVALID_SOCKET) 
	{ 
		if (mIsSending) 
		{ 
			return TRUE; 
		} 
 
		DWORD threadID = 0; 
		mSndThread = CreateThread(NULL, 0, SendingThrd,  
			this, 0, &threadID); 
		return (mSndThread != NULL); 
	} 
	return FALSE; 
} 
 
void CStreamSocket::StopSending(void) 
{ 
	if (mIsSending) 
	{ 
		Detach(); 
		if (mSndThread != NULL)  
		{ 
            WaitForSingleObject(mSndThread, INFINITE); 
			mSndThread = NULL; 
		} 
	} 
} 
 
DWORD WINAPI CStreamSocket::ReceivingThrd(void * pParam) 
{ 
	CStreamSocket * pSock = (CStreamSocket *) pParam; 
	if (pSock) 
	{ 
		pSock->mIsReceiving = TRUE; 
		pSock->ReceivingLoop(); 
		return 1; 
	}	 
	return 0; 
} 
 
DWORD WINAPI CStreamSocket::SendingThrd(void * pParam) 
{ 
	CStreamSocket * pSock = (CStreamSocket *) pParam; 
	if (pSock) 
	{ 
		pSock->mIsSending = TRUE; 
		pSock->SendingLoop(); 
		return 1; 
	}	 
	return 0; 
} 
 
// Used in the Net Receiver Filter 
void CStreamSocket::ReceivingLoop(void) 
{ 
	char   buf[1024]; 
	int    bytes = 0; 
	Pack_Header * pHeader = (Pack_Header *) buf; 
	PBYTE  pSampleBuffer; 
 
	while (mIsReceiving && mOwnerFilter) 
	{ 
		// Receive a pack header first 
		bytes = recv(mSocket, buf, sizeof(Pack_Header), 0); 
		if (bytes == SOCKET_ERROR || bytes == 0) 
		{ 
			Detach(); 
			mIsReceiving = FALSE; 
			break; 
		} 
 
		pHeader->my_ntoh(); 
		if (pHeader->pack_type == PT_AudioMediaType || 
			pHeader->pack_type == PT_VideoMediaType) 
		{ 
			// Receive media type 
			bytes = recv(mSocket, buf+sizeof(Pack_Header), pHeader->pack_size, 0); 
			if (bytes == SOCKET_ERROR || bytes == 0) 
			{ 
				Detach(); 
				mIsReceiving = FALSE; 
				break; 
			} 
			// Notify the filter to build filter graph 
			mOwnerFilter->SetupMediaType(pHeader->pack_type, buf+sizeof(Pack_Header),  
				pHeader->pack_size); 
		} 
		else 
		{ 
			// Receive media data 
			BOOL pass = FALSE; 
			do 
			{ 
				pass = mOwnerFilter->GetSampleBuffer(&pSampleBuffer); 
				if (!pass) 
				{ 
					Sleep(100); 
				} 
			} while (mIsReceiving && !pass); 
 
			long required = pHeader->pack_size; 
			long received = 0; 
			while (pass && mIsReceiving && required > 0) 
			{ 
				bytes = recv(mSocket, (char*)(pSampleBuffer+received), required, 0); 
				if (bytes == SOCKET_ERROR || bytes == 0) 
				{ 
					Detach(); 
					mIsReceiving = FALSE; 
					break; 
				} 
				received += bytes; 
				required -= bytes;	 
			} 
			// Deliver this sample 
			mOwnerFilter->DeliverHoldingSample(pHeader->pack_size); 
		//	Sleep(10); 
		} 
	} 
} 
 
void CStreamSocket::SendingLoop(void) 
{ 
}