c (linux/windows) http download get

一个http下载程序的c实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h>

#define RECVBUFSIZE    2048
#define READBUFSIZE     2048

/********************************************
功能:搜索字符串右边起的第一个匹配字符
********************************************/
char * Rstrchr(char * s, char x)  {
int i = strlen(s);
if(!(*s))  return 0;
while(s[i-1]) if(strchr(s + (i - 1), x))  return (s + (i - 1));  else i--;
return 0;
}

/********************************************
功能:把字符串转换为全小写
********************************************/
void ToLowerCase(char *s)  {
while(*s)  {
*s=tolower(*s);
s++;
}//while
}

/**************************************************************
功能:从字符串src中分析出网站地址和端口,并得到用户要下载的文件
***************************************************************/
void GetHost(char * src, char * web, char * file, int * port)  {
char * pA;
char * pB;
memset(web, 0, sizeof(web));
memset(file, 0, sizeof(file));
*port = 0;
if(!(*src))  return;
pA = src;
if(!strncmp(pA, "http://", strlen("http://")))  pA = src+strlen("http://");
else if(!strncmp(pA, "https://", strlen("https://")))  pA = src+strlen("https://");
pB = strchr(pA, '/');
if(pB)  {
memcpy(web, pA, strlen(pA) - strlen(pB));
if(pB+1)  {
memcpy(file, pB + 1, strlen(pB) - 1);
file[strlen(pB) - 1] = 0;
}
}
else  memcpy(web, pA, strlen(pA));
if(pB)  web[strlen(pA) - strlen(pB)] = 0;
else  web[strlen(pA)] = 0;
pA = strchr(web, ':');
if(pA)  *port = atoi(pA + 1);
else *port = 80;
}


int find_start(char *buf, int size)
{
int i;
char *p;
p = strstr(buf, "\r\n\r\n");
if(p) {
i = p - buf + 4;
if(i >= size)
i = -1;
}
else
i = -1;
return i;
}

//唯一的参数就是网址网址
int main(int argc, char **argv) {
int sockfd;
int fd;
struct hostent *host;
int portnumber;
char url[128];
char host_addr[256];
char host_file[1024];
char request[1024];
struct sockaddr_in server_sockaddr;
char recvbuf[RECVBUFSIZE];
int sendbytes, recvbytes, totalsend, totalsended;
int file_start_pos;

sprintf(url, "%s", argv[1]);
ToLowerCase(url);
GetHost(url, host_addr, host_file, &portnumber);
host = gethostbyname(host_addr);

sockfd = socket(PF_INET, SOCK_STREAM, 0);
server_sockaddr.sin_family = PF_INET;
server_sockaddr.sin_port = htons(portnumber);
server_sockaddr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_sockaddr.sin_zero), 8);
connect(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr));

sprintf(request, "GET /%s HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\n\
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n\
Host: %s:%d\r\nConnection: Keep-Alive\r\n\r\n", host_file, host_addr, portnumber);

sendbytes = 0;
totalsended = 0;            //already send
totalsend = strlen(request);        //will send
while(totalsended < totalsend) {   
sendbytes = send(sockfd, request+totalsended, totalsend - totalsended, 0);
totalsended += sendbytes;
}//while

fd = open("download", O_CREAT | O_TRUNC | O_RDWR, 0777);
recvbytes = recv(sockfd, recvbuf, RECVBUFSIZE, 0);    //delete the head
file_start_pos = find_start(recvbuf, recvbytes);
write(fd, recvbuf+file_start_pos, recvbytes-file_start_pos);
while((recvbytes = recv(sockfd, recvbuf, RECVBUFSIZE, 0)) > 0) {
write(fd, recvbuf, recvbytes);
}//while

close(fd);
close(sockfd);
return 0;
}//main()
 
 
/windows.............//
 

win32 http download

HTTPClient.h

#pragma once
#ifndef HTTPClient_H_
#define HTTPClient_H_
 
#include <string>
using   namespace   std;
 
class   HTTPClient
{
public :
     HTTPClient( void );
     ~HTTPClient( void );
 
     bool   DownloadFile(string serverName, int   port,string sourcePath, string fileName, string localDirectory);
};
#endif

  

HTTPClient.cpp

#include "StdAfx.h"
#include "HTTPClient.h"
#include <winsock.h>
#include <fstream>
//#include "Log.h"
#pragma comment(lib,"ws2_32.lib")
 
HTTPClient::HTTPClient( void )
{
}
 
HTTPClient::~HTTPClient( void )
{
}
 
bool   HTTPClient::DownloadFile(string serverName, int   port, string sourcePath, string fileName, string localDirectory)
{
     //Log &log = Log::getLog("HTTPClient","DownloadFile");
     //log.debug("\nserverName = %s; sourcePath = %s; fileName = %s\n",serverName.c_str(),sourcePath.c_str(),fileName.c_str());
 
     WSADATA wsaData;
     int   nRet;
 
     //
     // Initialize WinSock.dll
     //
     nRet = WSAStartup(0x101, &wsaData);
     if   (nRet)
     {
         //log.debug("\nWinSock.dll initialize failed. WSAStartup(): %d\n", nRet);
         WSACleanup();
         return   false ;
     }
     else       
     {
         //log.debug("\nWSAStartup success!\n");
     }
 
     //
     // Check WinSock version
     //
     if   (wsaData.wVersion != 0x101)
     {
         //log.debug("\nWinSock version not supported\n");
         WSACleanup();
         return   false ;
     }
     else
         {
             //log.debug("\nwsaData.wVersion ==0x101\n");
         }
 
     ofstream fout;
     string newfile = localDirectory + fileName;
     fout.open(newfile.c_str(),ios_base::binary);
     if (!fout.is_open())
     {
         //log.debug("open newfile error!");
     }
     else
         {
             //log.debug("open local newfile success!");
         }
 
     IN_ADDR        iaHost;
     LPHOSTENT    lpHostEntry;
 
     iaHost.s_addr = inet_addr(serverName.c_str());
     if   (iaHost.s_addr == INADDR_NONE)
     {
         // Wasn't an IP address string, assume it is a name
         lpHostEntry = gethostbyname(serverName.c_str());
     }
     else
     {
         // It was a valid IP address string
         lpHostEntry = gethostbyaddr(( const   char   *)&iaHost,
             sizeof ( struct   in_addr), AF_INET);
     }
     if   (lpHostEntry == NULL)
     {
         //log.debug("gethostbyname() error");
         return   false ;
     }
     else
         {
             //log.debug("gethostbyname() success!");
         }
 
     //   
     // Create a TCP/IP stream socket
     //
     SOCKET    Socket;   
 
     Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if   (Socket == INVALID_SOCKET)
     {
         //log.debug("socket() error");
         return   false ;
     }
     else
         {
             //log.debug("socket() success!");
         }
 
     //
     // Find the port number for the HTTP service on TCP
     //
     SOCKADDR_IN saServer;
     //LPSERVENT lpServEnt;
 
     //lpServEnt = getservbyname("http", "tcp");
     //if (lpServEnt == NULL)
     //  saServer.sin_port = htons(80);
     //else
     //  saServer.sin_port = lpServEnt->s_port;
 
     saServer.sin_port = htons(port);
 
     //
     // Fill in the rest of the server address structure
     //
     saServer.sin_family = AF_INET;
     saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
 
     //
     // Connect the socket
     //
     nRet = connect(Socket, (LPSOCKADDR)&saServer, sizeof (SOCKADDR_IN));
     if   (nRet == SOCKET_ERROR)
     {
         //log.debug("connect() error");
         closesocket(Socket);
         return   false ;
     }
     else
         {
             //log.debug("connect() success!");
         }
     
     //
     // Format the HTTP request
     //
     char   szBuffer[1024];
 
     string requestFile = sourcePath + fileName;
 
     sprintf (szBuffer, "GET %s\n" , requestFile.c_str());
     //log.debug("sended GET %s Request",requestFile.c_str());
     nRet = send(Socket, szBuffer, strlen (szBuffer), 0);
     if   (nRet == SOCKET_ERROR)
     {
         //log.debug("send() error");
         closesocket(Socket);   
         return   false ;
     }
 
     //
     // Receive the file contents and print to stdout
     //
     while (1)
     {
         // Wait to receive, nRet = NumberOfBytesReceived
         nRet = recv(Socket, szBuffer, sizeof (szBuffer), 0);
         if   (nRet == SOCKET_ERROR)
         {
             //log.debug("recv() error");
             break ;
         }
 
         //log.debug("\nrecv() returned %d bytes", nRet);
         // Did the server close the connection?
         if   (nRet == 0)
             break ;
         // Write to stdout
         //        fwrite(szBuffer, nRet, 1, stdout);
         fout.write(szBuffer,nRet);
     }
     closesocket(Socket);   
     fout.close();
 
     WSACleanup();
     return   true ;
}

调用示例:

#include "stdafx.h"
#include "HTTPClient.h"
 
int   _tmain( int   argc, _TCHAR* argv[])
{
 
     HTTPClient* client;
     client= new   HTTPClient();
     bool   a = client->DownloadFile( "127.0.0.1" ,80, "/" , "KeyBoardSelectionComboBox.zip" , "c:\\" );
     bool   b = client->DownloadFile( "www.zt.cn" ,88, "/ClientBin/" , "Main.xap" , "c:\\" );
     
     return   0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值