如何用c++写一个dht爬虫

如何用c++写一个dht爬虫,第1张

要想爬,先读取HTTP

读取后 进行字符串分割 

Http访问有两种方式,GET和POST,就编程来说GET方式相对简单点,它不用向服务器提交数据,程序中使用POST方式,

提交数据并从服务器获取返回值。

为实现Http访问,微软提供了二套API:WinINet, WinHTTP。WinHTTP比WinINet更加安全和健壮,可以这么认为WinHTTP是WinINet的升级版本。

程序中,通过一个宏的设置来决定是使用WinHttp还是WinINet。

#define USE_WINHTTP      //Comment this line to user wininet.

下面来说说实现Http访问的流程(两套API都一样的流程):

1, 首先我们打开一个Session获得一个HINTERNET session句柄

2, 然后我们使用这个session句柄与服务器连接得到一个HINTERNET connect句柄;

3, 然后我们使用这个connect句柄来打开Http 请求得到一个HINTERNET request句柄;

4, 这时我们就可以使用这个request句柄来发送数据与读取从服务器返回的数据;

5, 最后依次关闭request,connect,session句柄。

 

/***********************定义HTTP发送所用方法***********************************/

HINTERNET OpenSession(LPCWSTR userAgent = 0)

{

#ifdef USE_WINHTTP

    return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL)

#else

    return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)

#endif

}

HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo)

{

#ifdef USE_WINHTTP

    return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0)

#else

    return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0)

#endif

}

HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb, LPCWSTR objectName, int scheme)

{

    DWORD flags = 0

#ifdef USE_WINHTTP

    if (scheme == INTERNET_SCHEME_HTTPS) {

 闷颂       flags |= WINHTTP_FLAG_SECURE

    }

    return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags)

#else

    if 羡拍(scheme == INTERNET_SCHEME_HTTPS) {

        flags |= INTERNET_FLAG_SECURE

    }

    return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0)

#endif

}

BOOL AddRequestHeaders(HINTERNET hRequest, LPCWSTR header)

{

    SIZE_T len = lstrlenW(header)

#ifdef USE_WINHTTP

   蚂派郑 return WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD)

#else

    return HttpAddRequestHeaders(hRequest, header, DWORD(len), HTTP_ADDREQ_FLAG_ADD)

#endif

}

BOOL SendRequest(HINTERNET hRequest, const void* body, DWORD size)

{

#ifdef USE_WINHTTP

    return WinHttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size, size, 0)

#else

    return HttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size)

#endif

}

BOOL EndRequest(HINTERNET hRequest)

{

#ifdef USE_WINHTTP

    return WinHttpReceiveResponse(hRequest, 0)

#else

    // if you use HttpSendRequestEx to send request then use HttpEndRequest in here!

    return TRUE

#endif

}

BOOL QueryInfo(HINTERNET hRequest, int queryId, char* szBuf, DWORD* pdwSize)

{

#ifdef USE_WINHTTP

    return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0)

#else

    return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0)

#endif

}

BOOL ReadData(HINTERNET hRequest, void* buffer, DWORD length, DWORD* cbRead)

{

#ifdef USE_WINHTTP

    return WinHttpReadData(hRequest, buffer, length, cbRead)

#else

    return InternetReadFile(hRequest, buffer, length, cbRead)

#endif

}

void CloseInternetHandle(HINTERNET hInternet)

{

    if (hInternet)

{

#ifdef USE_WINHTTP

        WinHttpCloseHandle(hInternet)

#else

        InternetCloseHandle(hInternet)

#endif

    }

}

/**********************************************************/

///通过Http方式发送短信

string SendSMS_HTTP(const long ececcid,const string & password ,const string & msisdn, const string &smsContent)

{

 string rtnStr ="-1"

    HINTERNET hSession = 0

    HINTERNET hConnect = 0

    HINTERNET hRequest = 0

    wstring strHeader(L"Content-type: application/x-www-form-urlencoded\r\n")

    // Test data

    CrackedUrl crackedUrl(L"http://pi.f3.cn/SendSMS.aspx")

 string StrPostData = "ececcid=600000&password="+password+"&msisdn="+msisdn+"&smscontent="+smsContent+"&msgtype=5&longcode="

 

 StrPostData = string_To_UTF8(StrPostData)

    // Open session.

    hSession = OpenSession(L"HttpPost by lyz_sea@163.com")

    if (hSession == NULL) {

        cout<<"Error:Open session!\n"

        return "-1"

    }

    // Connect.

    hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort())

    if (hConnect == NULL) {

        cout<<"Error:Connect failed!\n"

        return "-1"

    }

    // Open request.

    hRequest = OpenRequest(hConnect, L"POST", crackedUrl.GetPath(), crackedUrl.GetScheme())

    if (hRequest == NULL) {

        cout<<"Error:OpenRequest failed!\n"

        return "-1"

   }

    // Add request header.

 if (!AddRequestHeaders(hRequest, strHeader.c_str())) {

        cout<<"Error:AddRequestHeaders failed!\n"

        return "-1"

    }

    // Send post data.

 if (!SendRequest(hRequest, StrPostData.c_str(), StrPostData.length())) {

        cout<<"Error:SendRequest failed!\n"

        return "-1"

    }

    // End request

    if (!EndRequest(hRequest)) {

        cout<<"Error:EndRequest failed!\n"

        return "-1"

    }

    char szBuf[BUF_SIZE]

    DWORD dwSize = 0

    szBuf[0] = 0

    // Query header info.

#ifdef USE_WINHTTP

    int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH

    int statusCodeId = WINHTTP_QUERY_STATUS_CODE

    int statusTextId = WINHTTP_QUERY_STATUS_TEXT

#else

    int contextLengthId = HTTP_QUERY_CONTENT_LENGTH

    int statusCodeId = HTTP_QUERY_STATUS_CODE

    int statusTextId = HTTP_QUERY_STATUS_TEXT

#endif

    dwSize = BUF_SIZE

    if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize)) {

        szBuf[dwSize] = 0

        cout<<"Content length: "<<szBuf<<endl

    }

    dwSize = BUF_SIZE

    if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize)) {

        szBuf[dwSize] = 0

        cout<<"Status code: "<< szBuf<<endl

    }

    dwSize = BUF_SIZE

    if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize)) {

        szBuf[dwSize] = 0

        cout<<"Status text:"<<szBuf<<endl

    }

    // read data.

    for () {

        dwSize = BUF_SIZE

        if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE) {

           break

        }

        if (dwSize <= 0) {

            break

        }

        szBuf[dwSize] = 0

        

  rtnStr =::UTF8_To_string(string(szBuf))

  cout<<rtnStr<<endl//Output 返回值

   

    }

    CloseInternetHandle(hRequest)

    CloseInternetHandle(hConnect)

    CloseInternetHandle(hSession)

 return  rtnStr

}

 

 

以上方法中用到的CrackURL方法在以下CrackURL.h文件中:

#pragma once

//#include<iostream>

//using namespace std

#define USE_WINHTTP    //Comment this line to user wininet.

 #ifdef USE_WINHTTP

     #include <winhttp.h>

     #pragma comment(lib, "winhttp.lib")

 #else

     #include <wininet.h>

     #pragma comment(lib, "wininet.lib")

 #endif

 // CrackedUrl

 class CrackedUrl {

     int m_scheme

     wstring m_host

     int m_port

     wstring m_path

 public:

     CrackedUrl(LPCWSTR url)

     {

         URL_COMPONENTS uc = { 0}

         uc.dwStructSize = sizeof(uc)

 

         const DWORD BUF_LEN = 256

 

         WCHAR host[BUF_LEN]

         uc.lpszHostName = host

         uc.dwHostNameLength = BUF_LEN

 

         WCHAR path[BUF_LEN]

         uc.lpszUrlPath = path

         uc.dwUrlPathLength = BUF_LEN

 

         WCHAR extra[BUF_LEN]

         uc.lpszExtraInfo = extra

         uc.dwExtraInfoLength = BUF_LEN

 

 #ifdef USE_WINHTTP

         if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc)) {

             cout<<"Error:WinHttpCrackUrl failed!\n"

         }

 

 #else

         if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc)) {

             printf("Error:InternetCrackUrl failed!\n")

         }

 #endif

         m_scheme = uc.nScheme

         m_host = host

         m_port = uc.nPort

         m_path = path

     }

 

     int GetScheme() const

     {

         return m_scheme

     }

 

     LPCWSTR GetHostName() const

     {

   return m_host.c_str()

    }

    int GetPort() const

     {

         return m_port

     }

 

     LPCWSTR GetPath() const

     {

   return m_path.c_str()

     }

 

     static string UrlEncode(const char* p)

     {

         if (p == 0) {

             return string()

         }

 

         string buf

 

        for () {

             int ch = (BYTE) (*(p++))

             if (ch == '\0') {

                 break

             }

 

             if (isalnum(ch) || ch == '_' || ch == '-' || ch == '.') {

                 buf += (char)ch

            }

            else if (ch == ' ') {

                buf += '+'

            }

            else {

                char c[16]

                wsprintfA(c, "%%%02X", ch)

                buf += c

            }

        }

        return buf

    }

}

循环过余答种及结果的i值不同。看你for循环及中断中有没有更改或引用该i值。

你同学说的对,DHT22传输一位时间仅几十us,就要求你的位接收及数据处理程序总的一竖搜慧个循环漏搭周期要小于DHT22位传输最小延时。你1mhz主频,还用for循环读取数据位,时间够呛。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8238220.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存