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

📄 clistensocket.cpp

📁 《DirectShow开发指南》配套代码代码,需要DirectX SDK 7以上支持。
💻 CPP
字号:
// 
// CListenSocket.cpp
// 

#include "stdafx.h"
#include "CListenSocket.h"
#include "..\MediaServer\MediaServerDlg.h"

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

//////////////////////////////////////////////////////////////////////////////
CListenSocket::CListenSocket()
{
	m_hSocket     = NULL;
	m_bListening  = false;
	m_nLimitCount = 1;
	// 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

}

CListenSocket::~CListenSocket()
{
	// Stop listening first!
	if (m_bListening)
		StopListen();
	// Close the listen socket
	if (m_hSocket)
	{
		closesocket(m_hSocket);
		m_hSocket = NULL;
	}
	// Release the client sockets
	SOCKET  pSock;
	POSITION pos = m_ClientList.GetHeadPosition();
	while (pos)
	{
		pSock = (SOCKET) m_ClientList.GetNext(pos);
		closesocket(pSock);
	}
	m_ClientList.RemoveAll();
	// Release the thread event
	if (m_hThrdFinish)
	{
		CloseHandle(m_hThrdFinish);
		m_hThrdFinish = NULL;
	}
}

// Create a socket and place it in listening state
bool CListenSocket::Create(int inPort)
{
	// Already start listening...
	if (m_hSocket)
		return true;

	// Create a TCP socket
	m_hSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_hSocket == INVALID_SOCKET)
	{
		m_hSocket = NULL;
		return false;
	}

	// Settings on socket
	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));

	// Bind socket and listen
	struct in_addr bindAddr;
	bindAddr.S_un.S_addr = INADDR_ANY;
	SOCKADDR_IN   saddr;
	memset(&saddr, 0, sizeof(SOCKADDR_IN));
	saddr.sin_addr   = bindAddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port   = htons((WORD)inPort);
	if (bind(m_hSocket, (SOCKADDR *)&saddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) 
	{
		closesocket(m_hSocket);
		m_hSocket = NULL;
		return false;
	}
	if (listen(m_hSocket, SOMAXCONN) !=0) 
	{
		closesocket(m_hSocket);
		m_hSocket = NULL;
		return false;
	}

	return true;
}

// Start up an independent thread to listen socket-connection blockingly
bool CListenSocket::StartListen(void)
{
	if (m_hSocket)
	{
		if (m_bListening)
			return true;

		// Start a thread
		m_bListening = true;
		ResetEvent(m_hThrdFinish);
		// Make socket blocking
		u_long   nonBlock = FALSE;
		ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
		AfxBeginThread((AFX_THREADPROC)CListenSocket::ListeningThrd, this);
		return true;
	}
	return false;
}

void CListenSocket::StopListen(void)
{
	if (m_hSocket && m_bListening)
	{
		m_bListening = false;
		// Change socket from blocking to nonblocking to terminate listening thread
	//	u_long   nonBlock = TRUE;
	//	ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
	//	WaitForSingleObject(m_hThrdFinish, 2000);
		// Close the socket
		closesocket(m_hSocket);
		m_hSocket    = NULL;	
	}
}

// Accept socket connection
bool CListenSocket::Accept(void)
{
	if (m_hSocket)
	{
		SOCKADDR_IN  saddr;
		int len = sizeof(SOCKADDR_IN);
		SOCKET accs = accept(m_hSocket, (SOCKADDR *)&saddr, &len);
		if (accs == INVALID_SOCKET)
			return false;
		
		// Connection limited checking...
		if (m_ClientList.GetCount() >= m_nLimitCount)
		{
			closesocket(accs);
			return true;
		}

		// Settings on the new created socket
		BOOL   sopt = TRUE;
		setsockopt(accs, IPPROTO_TCP, TCP_NODELAY, (char *)&sopt, sizeof(BOOL));
		setsockopt(accs, SOL_SOCKET, SO_DONTLINGER, (char *)&sopt, sizeof(BOOL));
		m_ClientList.AddTail(accs);
		// Send out a message
		::SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_NEW_SOCKET, 0, 0);
		return true;
	}
	return false;
}

// Socket listening thread, blockingly...
UINT CListenSocket::ListeningThrd(void *pParam)
{
	CListenSocket * pListen = (CListenSocket *) pParam;
	if (pListen == NULL)
		return 0;

	while (pListen->m_bListening)
	{
		// If accept failure, exit
		if (!pListen->Accept())
			break;
	}

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

// Connection limited feature
void CListenSocket::SetLimitConnection(int inMax)
{
	m_nLimitCount = inMax;
}

int CListenSocket::GetLimitConnection(void)
{
	return m_nLimitCount;
}

⌨️ 快捷键说明

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