C++ C++;从https下载文件

C++ C++;从https下载文件,c++,file,https,download,C++,File,Https,Download,我目前正在使用此功能从http下载文件,但无法使其适用于带有https的URL: bool DownloadFile(string url, LPCSTR filename){ string request; // HTTP Header // char buffer[BUFFERSIZE]; struct sockaddr_in serveraddr; int sock; WSADATA wsaData; int port = 80; i

我目前正在使用此功能从http下载文件,但无法使其适用于带有https的URL:

bool DownloadFile(string url, LPCSTR filename){
    string request; // HTTP Header //
    char buffer[BUFFERSIZE];
    struct sockaddr_in serveraddr;
    int sock;
    WSADATA wsaData;
    int port = 80;
    if(url.find("http://") != -1){
        string temp = url;
        url = temp.substr(url.find("http://") + 7);
    }
    int dm = url.find("/");
    string file = url.substr(dm);
    string shost = url.substr(0, dm);
    request += "GET " + file + " HTTP/1.0\r\n";
    request += "Host: " + shost + "\r\n";
    request += "\r\n";
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
        return FALSE;
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        return FALSE;
    memset(&serveraddr, 0, sizeof(serveraddr));
    hostent *record = gethostbyname(shost.c_str());
    in_addr *address = (in_addr * )record->h_addr;
    string ipd = inet_ntoa(* address);
    const char *ipaddr = ipd.c_str();
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(ipaddr);
    serveraddr.sin_port = htons(port);
    if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
        return FALSE;
    if (send(sock, request.c_str(), request.length(), 0) != request.length())
        return FALSE;
    int nRecv, npos;
    nRecv = recv(sock, (char*)&buffer, BUFFERSIZE, 0);
    string str_buff = buffer;
    npos = str_buff.find("\r\n\r\n");
    HANDLE hFile;
    hFile = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    DWORD ss;
    while((nRecv > 0) && (nRecv != INVALID_SOCKET)){
        if(npos > 0){
            char bf[BUFFERSIZE];
            memcpy(bf, buffer + (npos + 4), nRecv - (npos + 4));
            WriteFile(hFile, bf,nRecv - (npos + 4), &ss, NULL);
        }else{
            WriteFile(hFile, buffer, nRecv, &ss, NULL);
        }
        ZeroMemory(&buffer, sizeof(buffer));
        nRecv = recv(sock, (char*)&buffer, BUFFERSIZE, 0);
        str_buff = buffer;
        npos = str_buff.find("\r\n\r\n");
    }
    CloseHandle(hFile);
    closesocket(sock);
    WSACleanup();

    return TRUE;
}
bool下载文件(字符串url,LPCSTR文件名){
字符串请求;//HTTP头//
字符缓冲区[BUFFERSIZE];
serveraddr中的结构sockaddr\u;
int袜子;
WSADATA WSADATA;
int端口=80;
if(url.find(“http:/”)!=-1){
字符串temp=url;
url=temp.substr(url.find(“http:/”)+7);
}
int dm=url.find(“/”);
字符串文件=url.substr(dm);
字符串shost=url.substr(0,dm);
请求+=“获取”+文件+“HTTP/1.0\r\n”;
请求+=“主机:”+shost+“\r\n”;
请求+=“\r\n”;
if(WSAStartup(MAKEWORD(2,0),&wsaData)!=0)
返回FALSE;
if((sock=socket(PF_INET,sock_STREAM,IPPROTO_TCP))<0)
返回FALSE;
memset(&serveraddr,0,sizeof(serveraddr));
hostent*record=gethostbyname(shost.c_str());
地址=(地址*)记录->地址;
字符串ipd=inet_ntoa(*地址);
const char*ipaddr=ipd.c_str();
serveraddr.sin_family=AF_INET;
serveraddr.sin\u addr.s\u addr=inet\u addr(ipaddr);
serveraddr.sinu端口=htons(端口);
if(connect(sock,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0
返回FALSE;
if(发送(sock,request.c_str(),request.length(),0)!=request.length())
返回FALSE;
int nRecv,非营利组织;
nRecv=recv(sock,(char*)和缓冲区,缓冲区大小,0);
字符串str_buff=缓冲区;
npos=str_buff.find(“\r\n\r\n”);
处理文件;
hFile=CreateFileA(文件名、通用写入、文件共享写入、NULL、始终创建、文件属性正常、0);
SetFilePointer(hFile,0,NULL,FILE\u BEGIN);
德沃德·ss;
while((nRecv>0)和&(nRecv!=无效的_套接字)){
如果(非营利组织>0){
char-bf[BUFFERSIZE];
memcpy(bf,buffer+(npos+4),nRecv-(npos+4));
写文件(hFile,bf,nRecv-(npos+4),&ss,NULL);
}否则{
写文件(hFile、缓冲区、nRecv和ss、NULL);
}
零内存(&buffer,sizeof(buffer));
nRecv=recv(sock,(char*)和缓冲区,缓冲区大小,0);
str_buff=缓冲区;
npos=str_buff.find(“\r\n\r\n”);
}
闭合手柄(hFile);
插座;
WSACleanup();
返回TRUE;
}
有没有一种不用curl就可以从https下载文件的方法?如果可能的话,我更喜欢使用套接字或Boost。如果需要,我想从BitBucket下载一个文件


非常感谢

> P>如果使用Linux,可以使用C++调用shell命令并轻松下载。我发现它比编写实际的C++代码要容易得多。

检查,或者具体的例子。代码的可能副本不适用于HTTPS,因为它不想用SSL/TLS做任何事情。如果不想使用cURL,则必须在套接字代码之上使用SSL/TLS库,如OpenSSL、Microsoft自己的SChannel或WinSock安全扩展。或者使用第三方套接字库,如Asio。SSL/TLS需要手工实现很多工作。仅供参考,您现有的代码远不能成为一个可行或准确的HTTP客户端实现。如果不想使用第三方库,可以使用Microsoft的WinInet或WinHTTP API发送HTTP/HTTPS请求。