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

📄 workingthread.cpp

📁 这是一个代理服务器程序,它使用多线程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	else
	{
		strcpy(buf, "HTTP/1.1 200 OK\r\n");
		dwSize = dwFileLen;
	}
	
	sprintf(pszLine, "Content-length: %d\r\n", dwSize);
	strcat(buf, pszLine);
	strcpy(pszLine, "Proxy-agent: Ag-PersonalProxy/1.0\r\n");
	strcat(buf, pszLine);

	ContentType(pszFile, pszType);
	sprintf(pszLine, "Content-type: %s\r\n", pszType);
	strcat(buf, pszLine);
	
	strcat(buf, "\r\n");
	send(sck, buf, strlen(buf), 0);
	
	while(!feof(pFileContent))
	{
		dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent);
		iRet = send(sck, buf, dwSize, 0);
		if(iRet == SOCKET_ERROR)
			break;
	}
	fclose(pFileContent);

	return;
}


UINT WorkingThread(LPVOID lpVoid)
{
	int iRet, i;
	char content[512], buf[BUFFER_SIZE], pszMsg[1024], pszCode[256], pszLine[512], *pEnd;
	WORKPARAM * pThreadParam = (WORKPARAM*)lpVoid;
	DWORD dwRet, dwTotal, dwSize;
	sockaddr_in addrProxy2nd;
	SOCKET sckClient;
	REQUESTHEADER requestHeader;
	HTTPHEADER httpHeader;
	FILE* pFileContent;

	dwRet = WaitForSingleObject(g_hConnectionCount, INFINITE);
	if(g_nConnectionCount>=80)
	{
		ReleaseSemaphore(g_hConnectionCount, 1, NULL);
		OUTPUT("Too many connections, limit reached\r\n");
		strcpy(buf, "HTTP/1.1 431 Too many connections, limit reached\r\n"); send(pThreadParam->sckClient , buf, strlen(buf), 0);
		strcpy(buf, "Proxy-agent: Ag-PersonalProxy/1.0\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);
		strcpy(buf, "Content-type: text/html\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);

		pFileContent = fopen("g:\\ag\\personalproxy\\authorizationrequired.html", "rb");
		dwSize = _filelength(_fileno(pFileContent));
		sprintf(buf, "Content-length: %d\r\n", dwSize); send(pThreadParam->sckClient, buf, strlen(buf), 0);
		strcpy(buf, "\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);

		while(!feof(pFileContent))
		{
			dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent);
			send(pThreadParam->sckClient, buf, dwSize, 0);
		}
		closesocket(pThreadParam->sckClient);
		fclose(pFileContent);
		delete pThreadParam;
		return 0;
	}
	g_nConnectionCount++;
	ReleaseSemaphore(g_hConnectionCount, 1, NULL);

	while(1)
	{
		iRet = RecvRequest(pThreadParam->sckClient, buf, BUFFER_SIZE-1, &requestHeader);
		if(iRet==SOCKET_ERROR)
		{
			sprintf(pszMsg, "RecvRequest()=SOCKET_ERROR, WSAGetLastError()=%d", WSAGetLastError());
			OUTPUT(pszMsg);
			WaitForSingleObject(g_hConnectionCount, INFINITE);
			g_nConnectionCount--;
			ReleaseSemaphore(g_hConnectionCount, 1, NULL);
			delete pThreadParam;
			return 0;
		}
		dwTotal = iRet;

		for(i=0; i<g_nRefused; i++)
		{
			if(g_ulIpRefused[i]==pThreadParam->addr.sin_addr.S_un.S_addr)
			{
				OUTPUT("refused ip:");
				sprintf(content, "\t%d.%d.%d.%d\r\n",
					pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1,
					pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2,
					pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3,
					pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4);
				OUTPUT(content);
				strcpy(buf, "HTTP/1.1 432 Ip refused\r\n"); send(pThreadParam->sckClient , buf, strlen(buf), 0);
				strcpy(buf, "Proxy-agent: Ag-PersonalProxy/1.0\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);
				strcpy(buf, "Content-type: text/html\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);
				pFileContent = fopen("g:\\ag\\personalproxy\\notification.html", "rb");
				dwSize = _filelength(_fileno(pFileContent));
				sprintf(buf, "Content-length: %d\r\n", dwSize); send(pThreadParam->sckClient, buf, strlen(buf), 0);
				strcpy(buf, "\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);

					dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent);
					buf[dwSize] = NULL;
					sprintf(content, buf,
						pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1,
						pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2,
						pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3,
						pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4);
					send(pThreadParam->sckClient, content, strlen(content), 0);
				closesocket(pThreadParam->sckClient);
				fclose(pFileContent);
				goto _ThreadExit;
			}
		}
		if(requestHeader.dwFlag & REQUEST_UNAUTHORIZED)
		{
			OUTPUT("HTTP/1.1 407 Proxy authorization required agproxy.");
			sprintf(content, "\t%s\t%d.%d.%d.%d\r\n",
				requestHeader.pszUserPass,
				pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1,
				pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2,
				pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3,
				pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4);
			OUTPUT(content);
			//HTTP/1.0 407 Proxy authorization required
			strcpy(buf, "HTTP/1.1 407 Proxy authorization required\r\n"); send(pThreadParam->sckClient , buf, strlen(buf), 0);
			strcpy(buf, "Proxy-agent: Ag-PersonalProxy/1.0\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);
			strcpy(buf, "Content-type: image/jpeg\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);
			strcpy(buf, "Proxy-authenticate: basic realm=\"JutAg\"\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);
			pFileContent = fopen("g:\\ag\\personalproxy\\Authorization.jpg", "rb");
			dwSize = _filelength(_fileno(pFileContent));
			sprintf(buf, "Content-length: %d\r\n", dwSize); send(pThreadParam->sckClient, buf, strlen(buf), 0);
			strcpy(buf, "\r\n"); send(pThreadParam->sckClient, buf, strlen(buf), 0);

			while(!feof(pFileContent))
			{
				dwSize = fread(buf, 1, BUFFER_SIZE, pFileContent);
				send(pThreadParam->sckClient, buf, dwSize, 0);
			}
			fclose(pFileContent);
			continue;
			}
		break;
	}
	if(strstr(buf, "POST"))
	{
		OUTPUT(buf);
		OUTPUT("\r\n");
	}
	else
	{
		strncpy(content, buf, strstr(buf, "\r\n")-buf+2);
		content[strstr(buf, "\r\n")-buf] = NULL;
		OUTPUT(content);
	}
	sprintf(content, "\t%d.%d.%d.%d\r\n",
		pThreadParam->addr.sin_addr.S_un.S_un_b.s_b1,
		pThreadParam->addr.sin_addr.S_un.S_un_b.s_b2,
		pThreadParam->addr.sin_addr.S_un.S_un_b.s_b3,
		pThreadParam->addr.sin_addr.S_un.S_un_b.s_b4);
	OUTPUT(content);

	if(requestHeader.dwFlag & VIRTUAL_RESOURCE)
	{
		HttpService(requestHeader.pszUrl, pThreadParam->sckClient, buf, &requestHeader);
		goto _ThreadExit;
	}

	OUTPUT("Connecting to the second proxy.\r\n");
	addrProxy2nd.sin_family = AF_INET;
	addrProxy2nd.sin_port = htons(globalInfo.nPort2nd);
	addrProxy2nd.sin_addr.S_un.S_un_b.s_b1 = globalInfo.b1;
	addrProxy2nd.sin_addr.S_un.S_un_b.s_b2 = globalInfo.b2;
	addrProxy2nd.sin_addr.S_un.S_un_b.s_b3 = globalInfo.b3;
	addrProxy2nd.sin_addr.S_un.S_un_b.s_b4 = globalInfo.b4;

	sckClient = socket(AF_INET, SOCK_STREAM, 0);
	if(sckClient==INVALID_SOCKET)
	{
		closesocket(pThreadParam->sckClient);
		closesocket(sckClient);
		sprintf(pszMsg, "socket()=INVALID_SOCKET, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
		OUTPUT(pszMsg);
		goto _ThreadExit1;
	}
	iRet = connect(sckClient, (const sockaddr*)&addrProxy2nd, sizeof(addrProxy2nd));
	if(iRet==SOCKET_ERROR)
	{
		closesocket(pThreadParam->sckClient);
		closesocket(sckClient);
		sprintf(pszMsg, "connect()=SOCKET_ERROR, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
		OUTPUT(pszMsg);
		goto _ThreadExit1;
	}
	
	// send the data before	Proxy-Authorization:
	send(sckClient, buf, requestHeader.pszAuthBegin-buf, 0);
	strncpy(pszMsg, buf, requestHeader.pszAuthBegin-buf);
	pszMsg[requestHeader.pszAuthBegin-buf] = NULL;
//	TRACE(pszMsg);
	// send Authorization information to the second proxy
	sprintf(pszMsg, "%s:%s", globalInfo.pszUser, globalInfo.pszPasswd);
	Base64(pszMsg, pszCode);
	sprintf(content, "Proxy-Authorization: Basic %s==\r\n", pszCode);
	send(sckClient, content, strlen(content), 0);
//	TRACE(content);
//	send(sckClient, requestHeader.pszAuthBegin, requestHeader.pszAuthEnd-requestHeader.pszAuthBegin, 0);
	strncpy(pszMsg, requestHeader.pszAuthBegin, requestHeader.pszAuthEnd-requestHeader.pszAuthBegin);
	pszMsg[requestHeader.pszAuthBegin, requestHeader.pszAuthEnd-requestHeader.pszAuthBegin] = NULL;
//	TRACE(pszMsg);
	// send the rest information
	send(sckClient, requestHeader.pszAuthEnd, strlen(requestHeader.pszAuthEnd), 0);
	iRet = 1;
	while(dwTotal<requestHeader.dwContSize && iRet)
	{
		iRet = recv(pThreadParam->sckClient, buf, BUFFER_SIZE, 0);
		buf[iRet] = NULL;
		if(iRet==SOCKET_ERROR)
		{
			sprintf(pszMsg, "while(nTotal<requestHeader.dwContSize && iRet) recv()=SOCKET_ERROR, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
			OUTPUT(pszMsg);
			goto _ThreadExit;
		}
		if(iRet)
		{
			OUTPUT("_DEBUG_PRE_\t");OUTPUT(buf);
			send(sckClient, buf, iRet, 0);
			dwTotal += iRet;
		}
	}
//	TRACE(requestHeader.pszAuthEnd);

	// waiting for response from server
	iRet = RecvHeader(sckClient, buf, BUFFER_SIZE, &httpHeader);
	send(pThreadParam->sckClient, buf, iRet, 0);

	if(httpHeader.dwContSize==0)
	{
		goto _ThreadExit;
	}

	dwTotal = iRet-(httpHeader.pContBegin - buf);
	while(dwTotal<httpHeader.dwContSize && iRet)
	{
		iRet = recv(sckClient, buf, BUFFER_SIZE, 0);
		if(iRet==SOCKET_ERROR)
		{
			sprintf(pszMsg, "recv()=SOCKET_ERROR, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
			OUTPUT(pszMsg);
			goto _ThreadExit;
		}
		dwTotal += iRet;
		send(pThreadParam->sckClient, buf, iRet, 0);
	}

_ThreadExit:
	OUTPUT("Working thread terminated.\r\n");
	closesocket(sckClient);
	closesocket(pThreadParam->sckClient);

_ThreadExit1:
	WaitForSingleObject(g_hConnectionCount, INFINITE);
	g_nConnectionCount--;
	ReleaseSemaphore(g_hConnectionCount, 1, NULL);

	delete pThreadParam;
	return 0;
}

UINT ListeningThread(LPVOID lpVoid)
{
	int iRet, addrLen;
	sockaddr_in addr, addrAccept;
	SOCKET sckListen, sckAccept;
	char pszMsg[512];
	int nErrCount;
	hostent * pEnt;
	WORKPARAM * pWorkParam;

	OUTPUT("going to create socket.\r\n");

	sckListen = socket(AF_INET, SOCK_STREAM, 0);
	if(sckListen==INVALID_SOCKET)
	{
		sprintf(pszMsg, "INVALID_SOCKET, WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
		OUTPUT(pszMsg);
		return 0;
	}
	OUTPUT("Listening socket created successfully.\r\n");

	iRet = gethostname(pszMsg, 256);
	if(iRet)
	{
		sprintf(pszMsg, "Error occur when gethostname(), WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
		OUTPUT(pszMsg);
		return 0;
	}

	pEnt =gethostbyname(pszMsg);
	if(!pEnt)
	{
		sprintf(pszMsg, "Error occur when gethostbyname(), WSAGetLastError()=%d\r\nListening Thread terminated.\r\n", WSAGetLastError());
		OUTPUT(pszMsg);
		return 0;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(globalInfo.nPort);
	addr.sin_addr.S_un.S_un_b.s_b1 = pEnt->h_addr_list[0][0];
	addr.sin_addr.S_un.S_un_b.s_b2 = pEnt->h_addr_list[0][1];
	addr.sin_addr.S_un.S_un_b.s_b3 = pEnt->h_addr_list[0][2];
	addr.sin_addr.S_un.S_un_b.s_b4 = pEnt->h_addr_list[0][3];
	globalInfo._b1 = pEnt->h_addr_list[0][0];
	globalInfo._b2 = pEnt->h_addr_list[0][1];
	globalInfo._b3 = pEnt->h_addr_list[0][2];
	globalInfo._b4 = pEnt->h_addr_list[0][3];

	iRet = bind(sckListen, (const sockaddr*)&addr, sizeof(addr));
	if(iRet==SOCKET_ERROR)
	{
		sprintf(pszMsg, "SOCKET_ERROR, WSAGetLastError()=%d", WSAGetLastError());
		OUTPUT(pszMsg);
		return 0;
	}

	nErrCount = 0;
	OUTPUT("Listening...\r\n");
	iRet = listen(sckListen, SOMAXCONN);
	if(iRet==SOCKET_ERROR)
	{
		sprintf(pszMsg, "INVALID_SOCKET, WSAGetLastError()=%d", WSAGetLastError());
		OUTPUT(pszMsg);
		nErrCount++;
		if(nErrCount>=10)
		{
			sprintf(pszMsg, "nErrCount>=10, listening thread terminated.\r\n");
			return 0;
		}
	}
	nErrCount = 0;

	while(1)
	{
		addrLen = sizeof(addrAccept);
		sckAccept = accept(sckListen, (struct sockaddr*)&addrAccept, &addrLen);
		if(sckAccept==INVALID_SOCKET)
		{
			sprintf(pszMsg, "accept()=SOCKET_ERROR, WSAGetLastError()=%d", WSAGetLastError());
			OUTPUT(pszMsg);
			return 0;
		}
		OUTPUT("One client accepted successfully.\r\n");

		pWorkParam = new WORKPARAM;
		pWorkParam->sckClient = sckAccept;
		pWorkParam->addr = addrAccept;

		AfxBeginThread(WorkingThread, (LPVOID)pWorkParam, THREAD_PRIORITY_BELOW_NORMAL);
	}

	return 0;
}

⌨️ 快捷键说明

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