#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()
一个http下载程序的c实现
/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;
}
|