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; } }