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

📄 receiver.cpp

📁 PPC流行的播放软件gsplayer源码2.24版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	fd_set	fdRecv, fdError;
	struct timeval tv = {0, RECV_INTERVAL};
	RECV_BUF* pBuf;

	*pszRedirect = NULL;
#ifdef _UNICODE
	WideCharToMultiByte(CP_ACP, 0, pszURL, -1, szURL, MAX_URL, 0, 0);
	WideCharToMultiByte(CP_ACP, 0, m_szProxy, -1, szProxy, MAX_URL, 0, 0);
	WideCharToMultiByte(CP_ACP, 0, m_szUserAgent, -1, szUserAgent, MAX_URL, 0, 0);
#else
	strcpy(szURL, pszURL);
	strcpy(szProxy, m_szProxy);
	strcpy(szUserAgent, m_szUserAgent);
#endif
	if (!strlen(szURL))
		return FALSE;

	// URL傪夝愅偡傞
	// Proxy僒乕僶乕偑愝掕偝傟偰偄傞偲偒偼僒乕僶乕傾僪儗僗傪夝愅
	if (m_fUseProxy && strlen(szProxy)) {
		if (strncmp(szProxy, "http://", strlen("http://"))) {
			if (sscanf(szProxy, "%[^:/]:%d", szHostName, &nPort) < 2)
				nPort = RECV_HTTP;
		}
		else {
			if (sscanf(szProxy, "http://%[^:/]:%d", szHostName, &nPort) < 2)
				nPort = RECV_HTTP;
		}
		psz = szURL;	
	}
	else {
		if (strncmp(szURL, "http://", strlen("http://"))) {
			if (sscanf(szURL, "%[^:/]:%d", szHostName, &nPort) < 2)
				nPort = RECV_HTTP;
			psz = strchr(szURL, '/');
		}
		else {
			if (sscanf(szURL, "http://%[^:/]:%d", szHostName, &nPort) < 2)
				nPort = RECV_HTTP;
			psz = strchr(szURL + 7, '/');
		}
	}
	if (!strlen(szHostName))
		return FALSE;

	// socket偺嶌惉
	m_hSock = socket(PF_INET, SOCK_STREAM, 0);
	if (m_hSock == INVALID_SOCKET)
		return FALSE;

	// 傾僪儗僗偺庢摼
	addr = inet_addr(szHostName);
	if (addr == SOCKET_ERROR) {
		pHost = gethostbyname(szHostName);
		if (!pHost)
			return FALSE;
		addr = *((unsigned long*)(pHost->h_addr_list)[0]);
	}

	// 旕摨婜庴怣偵愗傝懼偊
	if (ioctlsocket(m_hSock, FIONBIO, &val) == SOCKET_ERROR)
		goto fail;

	// 愙懕
	memset(&sAddr, 0, sizeof(struct sockaddr_in));
	sAddr.sin_family = AF_INET;
	sAddr.sin_port = htons((u_short)nPort);
	sAddr.sin_addr.s_addr = addr;
	connect(m_hSock, (const sockaddr*)&sAddr, sizeof(sAddr));

	// 僞僀儉傾僂僩偡傞傑偱懸偮
	nTimeout = 0;
	while (TRUE) {
		if (m_fStop)
			goto fail;
		FD_ZERO(&fdRecv);
		FD_SET(m_hSock, &fdRecv);
		FD_ZERO(&fdError);
		FD_SET(m_hSock, &fdError);
		if (select(NULL, 0, &fdRecv, &fdError, &tv) != SOCKET_ERROR) {
			if (FD_ISSET(m_hSock, &fdError))
				goto fail;
			else if (FD_ISSET(m_hSock, &fdRecv))
				break;
		}

		nTimeout += RECV_INTERVAL;
		if (nTimeout > RECV_CONNECT_TIMEOUT)
			goto fail;
	}

	// Request(HTTP)偺憲怣
	sprintf(szRequest, "GET %s HTTP/1.0\r\nHost: %s\r\nAccept: */*\r\nIcy-MetaData:1\r\nUser-Agent: %s\r\n\r\n",
	psz ? psz : "/", szHostName, szUserAgent);
	//x-audiocast-udpport: %d\r\n 傑偩枹懳墳

	if (send(m_hSock, szRequest, strlen(szRequest), 0) == SOCKET_ERROR)
		goto fail;

	// ICY (HTTP)僿僢僟傪偡傋偰庴怣偡傞
	psz = NULL;
	while (!psz && RECV_BUFF_SIZE - nLen - 1 > 0) {
		// 僞僀儉傾僂僩偡傞傑偱懸偮
		nTimeout = 0;
		while (TRUE) {
			if (m_fStop)
				goto fail;
			FD_ZERO(&fdRecv);
			FD_SET(m_hSock, &fdRecv);
			if (select(NULL, &fdRecv, 0, 0, &tv) != SOCKET_ERROR && FD_ISSET(m_hSock, &fdRecv)) 
				break;

			nTimeout += RECV_INTERVAL;
			if (nTimeout > RECV_RECEIVE_TIMEOUT)
				goto fail;
		}

		int nRecv = recv(m_hSock, szRecv + nLen, RECV_BUFF_SIZE - nLen, 0);
		if (!nRecv || nRecv == SOCKET_ERROR)
			goto fail;

		nLen += nRecv;
		if (nRet == 0) {
			// 僄儔乕僐乕僪傪僠僃僢僋
			if (!sscanf(szRecv, " %*s %d", &nRet))
				goto fail;

			if (nRet != ICY_OK && nRet != ICY_REDIRECT)
				goto fail;
		}

		szRecv[nLen] = NULL;
		psz = strstr(szRecv, "\r\n\r\n");
	}

	if (!psz)	// 僿僢僟偑廔傢偭偰偄側偄
		goto fail;

	// 僿僢僟傪夝愅偡傞
	if (nRet == ICY_REDIRECT) {
		// 儕僟僀儗僋僩
		DisconnectServer();
		psz = strstr(szRecv, "Location: ");
		if (sscanf(psz, "Location: %256[^\r\n]", szURL) == 1) {
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, szURL, -1, pszRedirect, MAX_URL);
#else
			strncpy(pszRedirect, szURL, MAX_URL);
			pszRedirect[MAX_URL - 1] = NULL;
#endif
			return FALSE;
		}
	}

	// name
	psz = strstr(szRecv, "icy-name");
	if (psz) {
		m_fShoutcast = TRUE;
		psz += strlen("icy-name:");
		if (sscanf(psz, "%256[^\r\n]", szURL)) {
			LPSTR p = szURL;
			while (*p == ' ') p++;
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, p, -1, m_szIcyName, MAX_URL);
#else
			strcpy(m_szIcyName, p);
#endif
		}
	}
	psz = strstr(szRecv, "ice-name");
	if (psz) {
		m_fShoutcast = TRUE;
		psz += strlen("ice-name:");
		if (sscanf(psz, "%256[^\r\n]", szURL)) {
			LPSTR p = szURL;
			while (*p == ' ') p++;
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, p, -1, m_szIcyName, MAX_URL);
#else
			strcpy(m_szIcyName, p);
#endif
		}
	}

	// genre
	psz = strstr(szRecv, "icy-genre");
	if (psz) {
		m_fShoutcast = TRUE;
		psz += strlen("icy-genre:");
		if (sscanf(psz, "%256[^\r\n]", szURL)) {
			LPSTR p = szURL;
			while (*p == ' ') p++;
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, p, -1, m_szIcyGenre, MAX_URL);
#else
			strcpy(m_szIcyGenre, p);
#endif
		}
	}
	psz = strstr(szRecv, "ice-genre");
	if (psz) {
		m_fShoutcast = TRUE;
		psz += strlen("ice-genre:");
		if (sscanf(psz, "%256[^\r\n]", szURL)) {
			LPSTR p = szURL;
			while (*p == ' ') p++;
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, p, -1, m_szIcyGenre, MAX_URL);
#else
			strcpy(m_szIcyGenre, p);
#endif
		}
	}

	// url
	psz = strstr(szRecv, "icy-url");
	if (psz) {
		m_fShoutcast = TRUE;
		psz += strlen("icy-url:");
		if (sscanf(psz, "%256[^\r\n]", szURL)) {
			LPSTR p = szURL;
			while (*p == ' ') p++;
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, p, -1, m_szIcyURL, MAX_URL);
#else
			strcpy(m_szIcyURL, p);
#endif
		}
	}
	psz = strstr(szRecv, "ice-url");
	if (psz) {
		m_fShoutcast = TRUE;
		psz += strlen("ice-url:");
		if (sscanf(psz, "%256[^\r\n]", szURL)) {
			LPSTR p = szURL;
			while (*p == ' ') p++;
#ifdef _UNICODE
			MultiByteToWideChar(CP_ACP, 0, p, -1, m_szIcyURL, MAX_URL);
#else
			strcpy(m_szIcyURL, p);
#endif
		}
	}
	
	//psz = strstr(szRecv, "icy-pub");
	//psz = strstr(szRecv, "x-audiocast-udpport:");

	// MetaData
	psz = strstr(szRecv, "icy-metaint");
	if (psz) {
		psz += strlen("icy-metaint:");
		m_cbMetaData = atoi(psz);
	}
	else {
		m_cbMetaData = 0;
	}
	m_cbMetaDataInterval = m_cbMetaData;

	// 僿僢僟埲奜偺庴怣嵪傒僶僢僼傽傪僐僺乕偡傞
	pBuf = (RECV_BUF*)m_listBufFree.GetAt(0);
	psz = strstr(szRecv, "\r\n\r\n") + 4;
	pBuf->cbRecv = nLen - (psz - szRecv);
	memcpy(pBuf->pbBuf, psz, pBuf->cbRecv);

	// MetaData偺僠僃僢僋
	pBuf->cbRecv -= CheckMetaData(pBuf->pbBuf, pBuf->cbRecv);

	return TRUE;
fail:
	DisconnectServer();
	return FALSE;
}

void CReceiver::DisconnectServer()
{
	if (m_hSock != INVALID_SOCKET) {
		shutdown(m_hSock, -2);
		closesocket(m_hSock);
		m_hSock = INVALID_SOCKET;
	}
}

BOOL CReceiver::PrepareBuffer()
{
	CAutoLock lock(&m_csecBuf);
	for (int i = 0; i < (int)m_cBuf; i++) {
		RECV_BUF* p = new RECV_BUF;
		if (!p) goto fail;
		m_listBufFree.Add((DWORD)p);
	}
	m_eventBufFree.Set();
	m_eventBuf.Reset();
	return TRUE;

fail:
	UnprepareBuffer();
	return FALSE;
}

void CReceiver::UnprepareBuffer()
{
	CAutoLock lock(&m_csecBuf);
	int i;
	for (i = 0; i < m_listBufFree.GetCount(); i++) {
		RECV_BUF* p = (RECV_BUF*)m_listBufFree.GetAt(i);
		delete p;
	}
	m_listBufFree.RemoveAll();
	for (i = 0; i < m_listBuf.GetCount(); i++) {
		RECV_BUF* p = (RECV_BUF*)m_listBuf.GetAt(i);
		delete p;
	}
	m_listBuf.RemoveAll();

	m_eventBufFree.Set();
	m_eventBuf.Set();
}

int CReceiver::CheckMetaData(LPBYTE pbBuf, int cbBuf)
{
	if (!m_cbMetaData)
		return 0;

	static TCHAR sz[MAX_URL];
	if (m_cbMetaDataInterval < 0) {
		// 搑拞傑偱偼MetaData
		if (cbBuf + m_cbMetaDataInterval <= 0) {
			memcpy(m_bMetaDataBuf + m_cbMetaDataBuf, pbBuf, cbBuf);
			m_cbMetaDataBuf += cbBuf;
			m_cbMetaDataInterval += cbBuf; // 傑偨搑拞傑偱偟偐側偄...
			return cbBuf;
		}
		int cbMetaData = -m_cbMetaDataInterval;
		memcpy(m_bMetaDataBuf + m_cbMetaDataBuf, pbBuf, cbMetaData);
		m_cbMetaDataBuf += cbMetaData;
		memmove(pbBuf, pbBuf - m_cbMetaDataInterval, cbBuf - cbMetaData);
		m_cbMetaDataInterval = m_cbMetaData - (cbBuf - cbMetaData);

		if (m_cbMetaDataInterval < 0) { // 2005/01/16
			m_cbMetaDataInterval = m_cbMetaData;
			return CheckMetaData(pbBuf, cbBuf - cbMetaData) + cbMetaData;
		}

		// 僞僀僩儖偺捠抦傪峴偆
		if (GetStreamTitle(sz)) {
			NotifyMessage(MAP_MSG_STREAM_TITLE, (WPARAM)sz, 0);
		}
		return cbMetaData;
	}

	if (m_cbMetaDataInterval - cbBuf < 0) {
		LPBYTE pMetaData = pbBuf + m_cbMetaDataInterval;
		int nSize = *pMetaData * 16 + 1;
		if (m_cbMetaDataInterval + nSize > cbBuf) {
			// 搑拞傑偱偟偐側偄...
			if (*pMetaData) {
				m_cbMetaDataBuf = cbBuf - m_cbMetaDataInterval;
				memcpy(m_bMetaDataBuf, pMetaData, m_cbMetaDataBuf);
			}
			m_cbMetaDataInterval = cbBuf - m_cbMetaDataInterval - nSize; // 儅僀僫僗抣偵側傞
			return nSize + m_cbMetaDataInterval;
		}
		
		// MetaData偺撪梕傪庢傝弌偡
		if (*pMetaData) {
			m_cbMetaDataBuf = nSize;
			memcpy(m_bMetaDataBuf, pMetaData, m_cbMetaDataBuf);
		}

		// 僶僢僼傽傪媗傔傞
		cbBuf = cbBuf - m_cbMetaDataInterval - nSize;
		memmove(pMetaData, pMetaData + nSize, cbBuf);
		m_cbMetaDataInterval = m_cbMetaData - cbBuf;

		if (m_cbMetaDataInterval < 0) { // 2005/01/16
			m_cbMetaDataInterval = m_cbMetaData;
			return CheckMetaData(pMetaData, cbBuf) + nSize;
		}

		// 僞僀僩儖偺捠抦傪峴偆
		if (nSize > 1 && GetStreamTitle(sz)) {
			NotifyMessage(MAP_MSG_STREAM_TITLE, (WPARAM)sz, 0);
		}
		return nSize;
	}
	
	m_cbMetaDataInterval -= cbBuf;
	return 0;
}

void CReceiver::NotifyMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (m_hwndMessage) {
		PostMessage(m_hwndMessage, uMsg, wParam, lParam);
	}
}

⌨️ 快捷键说明

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