C++ 获取URL内容的实例

我就废话不多说了,大家还是直接看代码吧~

以下内容摘自StackOverFlow 链接

#ifndef HTTPUTIL_H#define HTTPUTIL_H#include <windows.h>#include <string>#include <stdio.h> using std::string; #pragma comment(lib,"ws2_32.lib")  void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename);SOCKET connectToServer(char *szServerName, WORD portNum);int getHeaderLength(char *content);char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut);  char *sendRequest(char szUrl[]) { WSADATA wsaData; //char szUrl[] = "http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp"; long fileSize; char *memBuffer, *headerBuffer;  memBuffer = headerBuffer = nullptr;  if (WSAStartup(0x101, &wsaData) != 0)  return nullptr;  memBuffer = readUrl2(szUrl, fileSize, &headerBuffer); printf("returned from readUrl\n"); printf("data returned:\n%s", memBuffer); if (fileSize != 0) {  //delete (memBuffer);  delete (headerBuffer); } WSACleanup(); return memBuffer;} void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename) { string::size_type n; string url = mUrl;  if (url.substr(0, 7) == "http://")  url.erase(0, 7);  if (url.substr(0, 8) == "https://")  url.erase(0, 8);  n = url.find('/'); if (n != string::npos) {  serverName = url.substr(0, n);  filepath = url.substr(n);  n = filepath.rfind('/');  filename = filepath.substr(n + 1); }  else {  serverName = url;  filepath = "/";  filename = ""; }} SOCKET connectToServer(char *szServerName, WORD portNum) { struct hostent *hp; unsigned int addr; struct sockaddr_in server; SOCKET conn;  conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (conn == INVALID_SOCKET)  return NULL;  if (inet_addr(szServerName) == INADDR_NONE) {  hp = gethostbyname(szServerName); } else {  addr = inet_addr(szServerName);  hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); }  if (hp == nullptr) {  closesocket(conn);  return NULL; }  server.sin_addr.s_addr = *((unsigned long *)hp->h_addr); server.sin_family = AF_INET; server.sin_port = htons(portNum); if (connect(conn, (struct sockaddr *)&server, sizeof(server))) {  closesocket(conn);  return NULL; } return conn;} int getHeaderLength(char *content) { const char *srchStr1 = "\r\n\r\n", *srchStr2 = "\n\r\n\r"; char *findPos; int ofset = -1;  findPos = strstr(content, srchStr1); if (findPos != nullptr) {  ofset = findPos - content;  ofset += strlen(srchStr1); }  else {  findPos = strstr(content, srchStr2);  if (findPos != nullptr) {   ofset = findPos - content;   ofset += strlen(srchStr2);  } } return ofset;} char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut) { const int bufSize = 512; char readBuffer[bufSize], sendBuffer[bufSize], tmpBuffer[bufSize]; char *tmpResult = nullptr, *result; SOCKET conn; string server, filepath, filename; long totalBytesRead, thisReadSize, headerLen;  mParseUrl(szUrl, server, filepath, filename);  / step 1, connect // conn = connectToServer((char *)server.c_str(), 80);  / step 2, send GET request / sprintf(tmpBuffer, "GET %s HTTP/1.0", filepath.c_str()); strcpy(sendBuffer, tmpBuffer); strcat(sendBuffer, "\r\n"); sprintf(tmpBuffer, "Host: %s", server.c_str()); strcat(sendBuffer, tmpBuffer); strcat(sendBuffer, "\r\n"); strcat(sendBuffer, "\r\n"); send(conn, sendBuffer, strlen(sendBuffer), 0);  // SetWindowText(edit3Hwnd, sendBuffer); printf("Buffer being sent:\n%s", sendBuffer);  / step 3 - get received bytes  // Receive until the peer closes the connection totalBytesRead = 0; while (1) {  memset(readBuffer, 0, bufSize);  thisReadSize = recv (conn, readBuffer, bufSize, 0);   if ( thisReadSize <= 0 )   break;   tmpResult = (char *)realloc(tmpResult, thisReadSize + totalBytesRead);   memcpy(tmpResult + totalBytesRead, readBuffer, thisReadSize);  totalBytesRead += thisReadSize; }  headerLen = getHeaderLength(tmpResult); long contenLen = totalBytesRead - headerLen; result = new char[contenLen + 1]; memcpy(result, tmpResult + headerLen, contenLen); result[contenLen] = 0x0; char *myTmp;  myTmp = new char[headerLen + 1]; strncpy(myTmp, tmpResult, headerLen); myTmp[headerLen] = NULL; delete (tmpResult); *headerOut = myTmp;  bytesReturnedOut = contenLen; closesocket(conn); return (result);}#endif // HTTPUTIL_H

测试代码:

#include <string>#include <stdio.h>#include "HttpUtil.h"#include <iostream>using std::string;using namespace std;  int main() { char *resData = sendRequest("http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp"); string str = resData; cout << endl << str << endl; delete resData; return 0;}

补充知识:C++处理URL的方法,项目有用到,过程记录如下

由于这块需要转换成unicode码,也就是将字符串传换成unicode码,因此需要对输入的字符串做处理,同时又分两种情况,中文 非中文的处理,要区别对待,首先要对输入的字符串进行识别:

int 是不是中文(char *str){char ch;while (1){ch = *str++;if (ch == 0){break;}  if (ch&0x80){if (*str & 0x80){return true;}}else{return false;}}return 0;}

然后要进行相应转换

//--------------------------------------------------------------------- //函数:W2C//功能:将16位wchar_t转换为 8位char[2]//参数:w_cn为待转换的16位字符,c_cn[]为转换后的8位字符//备注:wchar_t的高位字节应该存储在char数组的低位字节//作者:xxxx//---------------------------------------------------------------------void W2C(wchar_t w_cn , char c_cn[]){c_cn[0] = w_cn >> 8 ;c_cn[1] = (char)w_cn ;}

然后主体转换代码:

//-------------------------------------------------------------------//函数:ToHex//功能:将16位字符串转换为十六进制字符串//参数:待转换的字符串,字符串长度//返回值:转换后的字符串//作者:xxxx//-------------------------------------------------------------------CString ToHex(CString Data, long nDataLength){CString sResult;for (long nLoop=0; nLoop<nDataLength; nLoop++){wchar_t ch = Data.GetAt(nLoop);CHAR buff[MAX_PATH] = {0};LPCWSTR str = &ch;WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)str, -1, buff, MAX_PATH, 0, 0);if (IncludeChinese(buff)){char c_cn[2]={'0'};W2C(ch,c_cn);static const char *hex = "0123456789ABCDEF";for(int i=0;i<2;i++){unsigned char chHexA = hex[((unsigned char)(c_cn[i]) >> 4) & 0x0f];unsigned char chHexB = hex[(unsigned char)(c_cn[i]) & 0x0f];sResult += (char)chHexA;sResult += (char)chHexB;}}else{sResult += ch;} } return sResult;}

到这里基本上结束了~也查看了一些资料,虽说这个功能简单,但是过程有点曲折。但总算完成了,留个纪念吧~希望对其他人有帮助~希望大家多多支持。

最好的感觉就是你什么都跟我说。

C++ 获取URL内容的实例

相关文章:

你感兴趣的文章:

标签云: