www.pudn.com > AVChat0926.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() 
{ 
	mSocketReceiver      = INVALID_SOCKET; 
	mSocketSender        = INVALID_SOCKET; 
 
	mIsReceiving = FALSE; 
	mRcvThread   = NULL; 
 
	mTargetIP    = 0x7f000001; // 127.0.0.1 
	mTargetPort  = 10080; 
	mLocalPort   = 10080; 
 
	mMulticastIP = 0xef080808;  // 239.8.8.8 
 
	mOwnerFilter = NULL; 
} 
 
CStreamSocket::~CStreamSocket() 
{ 
	DeleteReceiver(); 
	DeleteSender(); 
	StopReceiving(); 
} 
 
void CStreamSocket::SetTargetIP(DWORD inIP) 
{ 
	mTargetIP = inIP; 
} 
 
DWORD CStreamSocket::GetTargetIP(void) 
{ 
	return mTargetIP; 
} 
 
void CStreamSocket::SetTargetIP(const char * inIP) 
{ 
	mTargetIP = ntohl(inet_addr(inIP)); 
} 
 
void CStreamSocket::GetTargetIP(char * outIP) 
{ 
	if (outIP) 
	{ 
		struct in_addr   in; 
		in.S_un.S_addr = htonl(mTargetIP); 
		char * pStr = inet_ntoa(in); 
		strcpy(outIP, pStr); 
	} 
} 
 
void CStreamSocket::SetTargetPort(WORD inPort) 
{ 
	mTargetPort = inPort; 
} 
 
WORD CStreamSocket::GetTargetPort(void) 
{ 
	return mTargetPort; 
} 
 
void CStreamSocket::SetLocalPort(WORD inPort) 
{ 
	mLocalPort = inPort; 
} 
 
WORD CStreamSocket::GetLocalPort(void) 
{ 
	return mLocalPort; 
} 
 
 
void CStreamSocket::SetOwnerFilter(CFilterNetReceiver * inFilter) 
{ 
	mOwnerFilter = inFilter; 
} 
 
SOCKET CStreamSocket::GetSocketSender() 
{ 
	return mSocketSender;	 
} 
 
SOCKET CStreamSocket::GetSocketReceiver() 
{ 
	return mSocketReceiver;	 
} 
 
BOOL CStreamSocket::StartReceiving(void) 
{ 
	// Create socket if necessary 
	if (mSocketReceiver == INVALID_SOCKET) 
	{ 
		CreateReceiver(); 
	} 
 
	if (mSocketReceiver != 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) 
	{ 
		DeleteReceiver(); 
		if (mRcvThread != NULL)  
		{ 
            WaitForSingleObject(mRcvThread, INFINITE); 
			mRcvThread = NULL; 
		} 
	} 
} 
 
DWORD WINAPI CStreamSocket::ReceivingThrd(void * pParam) 
{ 
	CStreamSocket * pSock = (CStreamSocket *) pParam; 
	if (pSock) 
	{ 
		pSock->mIsReceiving = TRUE; 
		pSock->ReceivingLoop(); 
		return 1; 
	}	 
	return 0; 
} 
 
// Used in the Net Receiver Filter 
void CStreamSocket::ReceivingLoop(void) 
{ 
	const  int nBufLen = 10000; 
	struct sockaddr_in  addr_cli; 
	int  addr_cli_len = sizeof(addr_cli); 
	char   buf[nBufLen]; 
	int    bytes = 0; 
	Pack_Header * pHeader = (Pack_Header *) buf; 
	PBYTE  pSampleBuffer; 
 
	while (mIsReceiving && mOwnerFilter) 
	{ 
		int addr_cli_len = sizeof(addr_cli); 
		bytes = recvfrom(mSocketReceiver, (char *)buf, nBufLen, 0, 
			(LPSOCKADDR) &addr_cli, (int *) &addr_cli_len); 
		if (bytes == SOCKET_ERROR || bytes == 0) 
		{ 
			TRACE("%d",WSAGetLastError()); 
			mIsReceiving = FALSE; 
		} 
		else 
		{ 
			// Receive media data 
			BOOL pass = FALSE; 
			do 
			{ 
				pass = mOwnerFilter->GetSampleBuffer(&pSampleBuffer); 
				if (!pass) 
				{ 
					Sleep(100); 
				} 
			} while (mIsReceiving && !pass); 
 
			pHeader->my_ntoh(); 
			memcpy(pSampleBuffer,buf + sizeof(Pack_Header),pHeader->pack_size); 
			// Deliver this sample 
			mOwnerFilter->DeliverHoldingSample(pHeader->pack_size); 
		} 
	} 
} 
 
 
BOOL CStreamSocket::CreateSender(void) 
{ 
	u_char flag = 1; 
	int    ret = 0; 
	DeleteSender(); 
 
	mSocketSender = socket(AF_INET, SOCK_DGRAM, 0); 
	if (mSocketSender != INVALID_SOCKET) 
	{ 
		return TRUE; 
	} 
 
	//设置SOCKET为可重用地址 
	ret = setsockopt(mSocketSender, SOL_SOCKET, SO_REUSEADDR,  
		(char*)&flag, sizeof(flag)); 
	if (ret != SOCKET_ERROR) 
	{ 
		return TRUE; 
	} 
	return FALSE; 
} 
 
void CStreamSocket::DeleteSender(void) 
{ 
	if (mSocketSender != INVALID_SOCKET) 
	{ 
		closesocket(mSocketSender); 
		mSocketSender = INVALID_SOCKET; 
	} 
} 
 
BOOL CStreamSocket::CreateReceiver(void) 
{ 
	DeleteReceiver(); 
 
	mSocketReceiver = socket(AF_INET, SOCK_DGRAM, 0); 
	if (mSocketReceiver != INVALID_SOCKET) 
	{ 
		BOOL flag = TRUE; 
		int ret = setsockopt(mSocketReceiver, SOL_SOCKET, SO_REUSEADDR,  
			(char *) &flag, sizeof(flag)); 
		if (ret == SOCKET_ERROR)  
		{ 
			DeleteReceiver(); 
			return FALSE; 
		} 
 
		SOCKADDR_IN  addr; 
		addr.sin_family      = AF_INET; 
		addr.sin_addr.s_addr = htonl(INADDR_ANY); 
		addr.sin_port        = htons(mLocalPort); 
		ret = bind(mSocketReceiver, (struct sockaddr*) &addr, sizeof(addr)); 
		if (ret == SOCKET_ERROR)  
		{ 
			DeleteReceiver(); 
			return FALSE; 
		} 
 
		// Join the multicast group (for receiving) 
		struct ip_mreq mreq;  
		mreq.imr_multiaddr.s_addr = htonl(mMulticastIP); 
		mreq.imr_interface.s_addr = INADDR_ANY; 
		ret = setsockopt(mSocketReceiver, IPPROTO_IP, IP_ADD_MEMBERSHIP,  
			(char *) &mreq, sizeof(mreq)); 
 
		flag = 0; 
		ret = setsockopt(mSocketReceiver, IPPROTO_IP, IP_MULTICAST_LOOP, 
			(char *)&flag,sizeof(flag)); 
		return TRUE; 
	} 
 
	return FALSE; 
} 
 
void CStreamSocket::DeleteReceiver(void) 
{ 
	if (mSocketReceiver != INVALID_SOCKET) 
	{ 
		closesocket(mSocketReceiver); 
		mSocketReceiver = INVALID_SOCKET; 
	} 
}