C++实现发送HTTP Get/Post请求

11 篇文章 1 订阅
3 篇文章 0 订阅

http://192.168.1.100/yanfabu/getLckData1.php?type=updateLand&data=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,zp,25,a220513023

void CCM3600App::SendERP(CString csResult)
{
	// TODO: 在此添加控件通知处理程序代码
	char a[1024];
	char b[1024];
	char c[1024];
	CString StrOne, StrTwo, StrThree;

	wchar_t *cWorker = g_csWorker.GetBuffer();
	std::string A = CStringA(cWorker);
	std::string B;
	CString strWorker, strWorker_End = L"";
	char dest_str[3];
	for (int i = 0; i < g_csWorker.GetLength(); i++)
	{
		g_f_wctou8(dest_str, cWorker[i]);
		B = UrlEncode(dest_str);
		strWorker = B.c_str();//std::string-->CString
		strWorker = strWorker.Left(9);
		strWorker_End += strWorker;
	}

	StrOne = "192.168.1.100";//hostname
	StrTwo = "/yanfabu/getLckData1.php?";//url
	//StrThree = _T("type=updateB&data=") + csResult;//para 发送的数据
	StrThree = _T("type=updateB&data=") + g_csTestData + L"," + g_csPlan + L"," + strWorker_End + L", " + g_csDate;//para 发送的数据
	WideCharToMultiByte(CP_ACP, 0, StrOne, -1, a, 1024, NULL, NULL);
	WideCharToMultiByte(CP_ACP, 0, StrTwo, -1, b, 1024, NULL, NULL);
	//WideCharToMultiByte(CP_UTF8, 0, StrThree, -1, c, 1024, NULL, NULL);
	WideCharToMultiByte(CP_ACP, 0, StrThree, -1, c, 1024, NULL, NULL);

	wchar_t* msg = _post(a, b, c);
	if (m_SendOKorNO == 1)
	{
		//AfxMessageBox(_T("发送成功!"));
		m_SendOKorNO = 0;
	}
	else
	{
		AfxMessageBox(_T("发送失败!"));
	}
}
//正在使用的发送http post请求的函数
wchar_t* _post(char* hostname, char* url, char* para)
{
	WSADATA wsa;
	wchar_t* msg;
	DWORD dwNum;
	/*初始化socket资源*/
	if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0)
	{
		dwNum = MultiByteToWideChar(CP_ACP, 0, "初始化失败", -1, NULL, 0);
		msg = new wchar_t[dwNum];
		MultiByteToWideChar(CP_ACP, 0, "初始化失败", -1, msg, dwNum);
		return msg;   //代表失败
	}
	//初始化socket
	SOCKET Client_Sock = socket(AF_INET, SOCK_STREAM, 0);

	struct hostent* host_addr = gethostbyname(hostname);
	sockaddr_in sin;
	sin.sin_family = AF_INET;
	//设置端口号 这里设置为80 可以改为参数获取
	sin.sin_port = htons((unsigned short)80);
	sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list);

	int ret = connect(Client_Sock, (const struct sockaddr *)&sin, sizeof(sockaddr_in));

	if (ret == -1)
	{
		dwNum = MultiByteToWideChar(CP_ACP, 0, "连接失败", -1, NULL, 0);
		msg = new wchar_t[dwNum];
		MultiByteToWideChar(CP_ACP, 0, "连接失败", -1, msg, dwNum);
		return msg;   //代表失败
	}
	//拼接请求信息
	char send_str[2048] = { NULL };
	strcat(send_str, "POST ");
	strcat(send_str, url);
	strcat(send_str, " HTTP/1.1\r\n");
	strcat(send_str, "Accept: */*\r\n");
	strcat(send_str, "Accept-Language: zh-cn\r\n");
	strcat(send_str, "host:");
	strcat(send_str, hostname);
	strcat(send_str, "\r\n");
	strcat(send_str, "Content-Type: application/x-www-form-urlencoded\r\n");
	strcat(send_str, "Content-Length:");
	char len[2048] = { NULL };
	sprintf(len, "%d", strlen(para));//发送数据的格式 grade=
	strcat(send_str, len);
	strcat(send_str, "\r\n");
	strcat(send_str, "Connection:close\r\n\r\n");
	strcat(send_str, para);
	//发送请求
	if (send(Client_Sock, send_str, strlen(send_str), 0) == -1)
	{
		dwNum = MultiByteToWideChar(CP_ACP, 0, "发送失败", -1, NULL, 0);
		msg = new wchar_t[dwNum];
		MultiByteToWideChar(CP_ACP, 0, "发送失败", -1, msg, dwNum);
		m_SendOKorNO = 0;
		return msg;   //代表失败
	}
	else
	{
		m_SendOKorNO = 1;
	}

	char cs_str[1024] = { NULL };
	char recv_str[8192] = { NULL };
	//获取网页响应内容
	while (true)
	{
		//接收响应内容
		int recv_num = recv(Client_Sock, cs_str, strlen(cs_str) + 1, 0);
		if (recv_num == 0)
		{
			break;
		}
		else if (recv_num < 0)
		{
			char return_str[512] = { NULL };
			char return_num[20] = { NULL };
			sprintf(return_num, "%d", strlen(recv_str));
			strcat(return_str, recv_str);
			strcat(return_str, "|接收出错|");
			sprintf(return_num, "%d", WSAGetLastError());
			strcat(return_str, return_num);


			dwNum = MultiByteToWideChar(CP_ACP, 0, return_str, -1, NULL, 0);
			msg = new wchar_t[dwNum];
			MultiByteToWideChar(CP_ACP, 0, return_str, -1, msg, dwNum);
			return msg;   //代表失败
		}
		//接收正常拼接字符串
		strcat(recv_str, cs_str);
		memset(cs_str, 0, sizeof(cs_str));
	}
	//只获取 报头信息后面的 返回值
	char* re_msg = strstr(recv_str, "\r\n\r\n");
	//转换字符串
	dwNum = MultiByteToWideChar(CP_UTF8, 0, re_msg, -1, NULL, 0);
	msg = new wchar_t[dwNum];
	MultiByteToWideChar(CP_UTF8, 0, re_msg, -1, msg, dwNum);

	//关闭socket
	closesocket(Client_Sock);
	WSACleanup();
	//返回接收到的响应字符串
	return msg;
}
//正在使用的发送http get请求的函数
wchar_t* _get(char* hostname, char* url, char* para)
{
	WSADATA wData;
	::WSAStartup(MAKEWORD(2, 2), &wData);
	wchar_t* msg;
	DWORD dwNum;
	SOCKET Client_Sock = socket(AF_INET, 1, 0);
	struct sockaddr_in sin = { 0 };
	int Ret = 0;
	int AddrLen = 0;
	HANDLE hThread = 0;

	//拼接请求信息 //POST
	char send_str[2048] = { NULL };
	strcat(send_str, "GET ");
	strcat(send_str, url);
	strcat(send_str, para);
	strcat(send_str, " HTTP/1.1\r\n");
	strcat(send_str, "Connection:Keep-Alive\r\n");
	strcat(send_str, "Accept-Encoding:gzip, deflate\r\n");
	strcat(send_str, "Accept-Language:zh-CN,en,*\r\n");
	strcat(send_str, "host:");
	strcat(send_str, hostname);
	strcat(send_str, "\r\n");
	strcat(send_str, "User-Agent:Mozilla/5.0\r\n\r\n");
	char addIp[256] = { 0 };
	theApp.GetIpByDomainName(hostname, addIp);
	sin.sin_addr.s_addr = inet_addr(addIp);
	sin.sin_port = htons(80);;
	sin.sin_family = AF_INET;
	char bufRecv[3069] = { 0 };
	int errNo = 0;
	errNo = connect(Client_Sock, (sockaddr*)&sin, sizeof(sin));

	char cs_str[1024] = { NULL };
	char recv_str[8192] = { NULL };
	if (errNo == 0)
	{
		//如果发送成功,则返回发送成功的字节数;
		if (send(Client_Sock, send_str, strlen(send_str), 0) > 0)
		{
			m_SendOKorNO = 1;
		}
		else
		{
			m_SendOKorNO = 0;
		}
		//如果接受成功,则返回接受的字节数;
		if (recv(Client_Sock, cs_str, 3069, 0) > 0)
		{
			//char return_str[512] = { NULL };
			//char return_num[20] = { NULL };
			//sprintf(return_num, "%d", strlen(recv_str));
			//strcat(return_str, recv_str);
			//strcat(return_str, "|接收出错|");
			//sprintf(return_num, "%d", WSAGetLastError());
			//strcat(return_str, return_num);
			//dwNum = MultiByteToWideChar(CP_ACP, 0, return_str, -1, NULL, 0);
			//msg = new wchar_t[dwNum];
			//MultiByteToWideChar(CP_ACP, 0, return_str, -1, msg, dwNum);
			//return msg;   //代表失败
		}
	}
	else
	{
		errNo = WSAGetLastError();
	}
	//接收正常拼接字符串
	strcat(recv_str, cs_str);
	memset(cs_str, 0, sizeof(cs_str));
	//只获取 报头信息后面的 返回值
	char* re_msg = strstr(recv_str, "\r\n\r\n");
	//转换字符串
	dwNum = MultiByteToWideChar(CP_UTF8, 0, re_msg, -1, NULL, 0);
	msg = new wchar_t[dwNum];
	MultiByteToWideChar(CP_UTF8, 0, re_msg, -1, msg, dwNum);

	//char*和CString的转换
	msg[dwNum] = '\0';
	CString str;
	str.Append(msg);
	g_csErpRecData = str;
	//关闭socket
	closesocket(Client_Sock);
	WSACleanup();
	//返回接收到的响应字符串
	return msg;
}
std::string CCM3600App::UrlEncode(const std::string& src)
{
	static    char hex[] = "0123456789ABCDEF";
	std::string dst;

	for (size_t i = 0; i < src.size(); i++)
	{
		unsigned char ch = src[i];
		if (isalnum(ch))
		{
			dst += ch;
		}
		else
			if (src[i] == ' ')
			{
				dst += '+';
			}
			else
			{
				unsigned char c = static_cast<unsigned char>(src[i]);
				dst += '%';
				dst += hex[c / 16];
				dst += hex[c % 16];
			}
	}
	return dst;
}
BOOL CCM3600App::GetIpByDomainName(char *szHost, char* szIp)
{
	WSADATA        wsaData;

	HOSTENT   *pHostEnt;
	int             nAdapter = 0;
	struct       sockaddr_in   sAddr;
	if (WSAStartup(0x0101, &wsaData))
	{
		printf(" gethostbyname error for host:\n");
		return FALSE;
	}

	pHostEnt = gethostbyname(szHost);
	if (pHostEnt)
	{
		if (pHostEnt->h_addr_list[nAdapter])
		{
			memcpy(&sAddr.sin_addr.s_addr, pHostEnt->h_addr_list[nAdapter], pHostEnt->h_length);
			sprintf(szIp, "%s", inet_ntoa(sAddr.sin_addr));
		}
	}
	else
	{
		// 		DWORD  dwError = GetLastError();
		// 		CString  csError;
		// 		csError.Format("%d", dwError);
	}
	WSACleanup();
	return TRUE;
}
size_t  CCM3600App::g_f_wctou8(char * dest_str, const wchar_t src_wchar)
{

	int count_bytes = 0;

	wchar_t byte_one = 0, byte_other = 0x3f; // 用于位与运算以提取位值0x3f—>00111111

	unsigned char utf_one = 0, utf_other = 0x80; // 用于”位或”置标UTF-8编码0x80—>1000000

	wchar_t tmp_wchar = L'0'; // 用于宽字符位置析取和位移(右移位)

	unsigned char tmp_char = L'0';

	if (!src_wchar)//

		return (size_t)-1;

	for (;;) // 检测字节序列长度

	{

		if (src_wchar <= 0x7f) { // <=01111111

			count_bytes = 1; // ASCII字符: 0xxxxxxx( ~ 01111111)

			byte_one = 0x7f; // 用于位与运算, 提取有效位值, 下同

			utf_one = 0x0;

			break;

		}

		if ((src_wchar > 0x7f) && (src_wchar <= 0x7ff)) { // <=0111,11111111

			count_bytes = 2; // 110xxxxx 10xxxxxx[1](最多个位, 简写为*1)

			byte_one = 0x1f; // 00011111, 下类推(1位的数量递减)

			utf_one = 0xc0; // 11000000

			break;

		}

		if ((src_wchar > 0x7ff) && (src_wchar <= 0xffff)) { //0111,11111111<=11111111,11111111

			count_bytes = 3; // 1110xxxx 10xxxxxx[2](MaxBits: 16*1)

			byte_one = 0xf; // 00001111

			utf_one = 0xe0; // 11100000

			break;

		}

		if ((src_wchar > 0xffff) && (src_wchar <= 0x1fffff)) { //对UCS-4的支持..

			count_bytes = 4; // 11110xxx 10xxxxxx[3](MaxBits: 21*1)

			byte_one = 0x7; // 00000111

			utf_one = 0xf0; // 11110000

			break;

		}

		if ((src_wchar > 0x1fffff) && (src_wchar <= 0x3ffffff)) {

			count_bytes = 5; // 111110xx 10xxxxxx[4](MaxBits: 26*1)

			byte_one = 0x3; // 00000011

			utf_one = 0xf8; // 11111000

			break;

		}

		if ((src_wchar > 0x3ffffff) && (src_wchar <= 0x7fffffff)) {

			count_bytes = 6; // 1111110x 10xxxxxx[5](MaxBits: 31*1)

			byte_one = 0x1; // 00000001

			utf_one = 0xfc; // 11111100

			break;

		}

		return (size_t)-1; // 以上皆不满足则为非法序列

	}

	// 以下几行析取宽字节中的相应位, 并分组为UTF-8编码的各个字节

	tmp_wchar = src_wchar;

	for (int i = count_bytes; i > 1; i--)

	{ // 一个宽字符的多字节降序赋值

		tmp_char = (unsigned char)(tmp_wchar & byte_other);///后位与byte_other 00111111

		dest_str[i - 1] = (tmp_char | utf_other);/// 在前面加—-跟或

		tmp_wchar >>= 6;//右移位

	}

	//这个时候i=1

	//对UTF-8第一个字节位处理,

	//第一个字节的开头”1”的数目就是整个串中字节的数目

	tmp_char = (unsigned char)(tmp_wchar & byte_one);//根据上面附值得来,有效位个数

	dest_str[0] = (tmp_char | utf_one);//根据上面附值得来1的个数

	// 位值析取分组__End!

	return count_bytes;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值