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

📄 httprequest.c

📁 利用免费网关发送短信
💻 C
字号:



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 预处理。
#include <WinSock2.h>
#include "HttpRequest.h"

#ifdef UNICODE
#undef UNICODE
#endif // UNICODE

#define __TRY
#define __LEAVE(vResult) hrError = vResult; goto __Finally
#define __FINALLY __Finally:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 发送通知消息
__inline BOOL WINAPI SendHRNotify(HWND hNotify, WPARAM wParam, LPARAM lParam)
{
	if (hNotify)
	{
		return (BOOL) SendMessage(hNotify, UM_HRNOTIFY, wParam, lParam);
		//if (IsWindow(hNotify))
		//{
		//	return (BOOL) SendMessage(hNotify, UM_HRNOTIFY, wParam, lParam);
		//}
		//else
		//{
		//	return (BOOL) ((WNDPROC) hNotify)(NULL, UM_HRNOTIFY, wParam, lParam);
		//}
	}
	return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 发送 HTTP/1.1 请求,并接收返回数据。
HRERROR WINAPI HttpRequest(LPSTR pszServer, USHORT uPort, LPCSTR pszUri, 
						   LPSTR pszHost, LPCSTR pszRefer, LPCSTR pszCookie,
						   LPCBYTE pbPost, UINT uPost, LPBYTE pbReceive, LPUINT puReceive, 
						   LPSTR pszProxy, USHORT uProxy, BOOL bResolve, HWND hNotify)

{
	PBYTE p;
	int iSize;
	BOOL bProxy;
	UINT uHeader;
	UINT uReceive;
	SOCKET sSocket;
	HRERROR hrError;
	HOSTENT *pHostent;
	char szRequest[2048];
	SOCKADDR_IN saiAddress;

	__TRY
	{
		// 检查参数。
		if ((pszServer == NULL) || (pszUri == NULL) || (pszHost == NULL))
		{
			__LEAVE(HRERROR_ARGUMENT);
		}

		// 判断是否使用了代理服务器。
		bProxy = pszProxy && pszProxy[0];

		// 创建 Socket。
		sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (sSocket == INVALID_SOCKET)
		{
			__LEAVE(HRERROR_SOCKET);
		}

		// 填写 SOCKADDR_IN 结构。
		saiAddress.sin_family = AF_INET;
		saiAddress.sin_port = htons(bProxy ? uProxy : uPort);
		saiAddress.sin_addr.s_addr = inet_addr((bProxy ? pszProxy : pszServer));
		if (saiAddress.sin_addr.s_addr == INADDR_NONE)
		{			
			// 如果输入的不是 IP 地址,尝试进行域名转换。
			if (SendHRNotify(hNotify, HRNOTIFY_CONNECT, (LPARAM) (bProxy ? pszProxy : pszServer)))
			{
				__LEAVE(HRERROR_CANCELED);
			}
			pHostent = gethostbyname((bProxy ? pszProxy : pszServer));
			if (pHostent == NULL)
			{
				// 解析域名失败。
				__LEAVE(HRERROR_RESOLVEDNS);
			}

			// 解析域名成功,修改服务器地址。
			if (bResolve)
			{
				wsprintf((bProxy ? pszProxy : pszServer), "%d.%d.%d.%d",
					(BYTE) pHostent->h_addr[0],
					(BYTE) pHostent->h_addr[1],
					(BYTE) pHostent->h_addr[2],
					(BYTE) pHostent->h_addr[3]);
			}

			// 设置 SOCKADDR_IN 地址值。
			saiAddress.sin_addr.s_addr = *((PULONG) pHostent->h_addr);
		}

		// 连接服务器。
		if (SendHRNotify(hNotify, HRNOTIFY_CONNECT, (LPARAM) (bProxy ? pszProxy : pszServer)))
		{
			__LEAVE(HRERROR_CANCELED);
		}
		if (connect(sSocket, (PSOCKADDR) &saiAddress, sizeof(saiAddress)) == SOCKET_ERROR)
		{
			__LEAVE(HRERROR_CONNECT);
		}

		// 构造 HTTP/1.1 请求。
		lstrcpy(szRequest, (pbPost ? "POST " : "GET "));
		if (bProxy)
		{
			wsprintf(szRequest + lstrlen(szRequest), "http://%s:%d", pszHost, uPort);
		}
		wsprintf(szRequest + lstrlen(szRequest), "%s HTTP/1.1\r\n", pszUri);
		if (pszRefer)
		{
			wsprintf(szRequest + lstrlen(szRequest), "Refer: %s\r\n", pszRefer);
		}
		if (pbPost)
		{
			wsprintf(szRequest + lstrlen(szRequest), "Content-Length: %d\r\n", uPost);
		}
		if (pszCookie)
		{
			wsprintf(szRequest + lstrlen(szRequest), "Cookie: %s\r\n", pszCookie);
		}
		wsprintf(szRequest + lstrlen(szRequest), 
			"Accept: */*\r\n"
			"Accept-Language: zh-cn\r\n"
			"Content-Type: application/x-www-form-urlencoded\r\n"
			"Accept-Encoding: gzip, deflate\r\n"
			"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2)\r\n"
			"Host: %s\r\n\r\n", pszHost);

		// 发送请求。
		iSize = lstrlen(szRequest);
		if (SendHRNotify(hNotify, HRNOTIFY_SEND, iSize))
		{
			__LEAVE(HRERROR_CANCELED);
		}
		if (send(sSocket, szRequest, iSize, 0) == SOCKET_ERROR)
		{
			__LEAVE(HRERROR_SEND);
		}

		// 发送 POST 数据。
		if (pbPost)
		{
			if (SendHRNotify(hNotify, HRNOTIFY_SEND, uPost))
			{
				__LEAVE(HRERROR_CANCELED);
			}
			if (send(sSocket, pbPost, uPost, 0) == SOCKET_ERROR)
			{
				__LEAVE(HRERROR_SEND);
			}
		}

		// 如果要接收数据。
		if ((pbReceive) && (puReceive) && (*puReceive > HRNOTIFY_DISCONNECT))
		{
			// 接收返回数据。
			for(uReceive = 0, uHeader = 0; uReceive < *puReceive; uReceive += iSize)
			{
				// 接收数据。
				if (SendHRNotify(hNotify, *puReceive, uReceive))
				{
					__LEAVE(HRERROR_CANCELED);
				}
				iSize = recv(sSocket, pbReceive + uReceive, min(2048, *puReceive - uReceive), 0);
				if (iSize < 1)
				{
					break;
				}

				if ((strcmpi(pszUri, "/image.jsp") == 0) && (uReceive + iSize > 1300))
				{
					uReceive += iSize;
					break;
				}

				if (uHeader == 0)
				{
					// 分析接收到的数据是否包含完整的 HTTP 头部。
					p = strstr(pbReceive, "\r\n\r\n");
					if (p)
					{
						// 取得 HTTP 头的大小。
						uHeader = (UINT) (p - pbReceive + 4);	// sizeof("\r\n\r\n")

						// 分析接收到的数据是否指定了 Content-Length 值。
						p = strstr(pbReceive, "Content-Length: ");
						if (p)
						{
							if (*puReceive > (uHeader + atoi(p + 16)))
							{
								// 修正要接收的数据字节数。
								*puReceive = uHeader + atoi(p + 16);
							}
						}
					}
				}
			}

			// 设置接收数据总字节数。
			*puReceive = uReceive;
			if (uReceive < 1)
			{
				__LEAVE(HRERROR_RECEIVE);
			}
		}

		// 设置成功返回值。
		hrError = HRERROR_SUCCESS;
	}
	__FINALLY
	{
		// 关闭 Socket
		if (sSocket != INVALID_SOCKET)
		{
			closesocket(sSocket);
		}

		SendHRNotify(hNotify, HRNOTIFY_DISCONNECT, hrError);

		// 返回结果
		return hrError;
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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