|
配置文件存放在WEB目录中的某些目录,相对路径已知,发现用系统自带的wget工具下载配置文件时,必须要把文件完整下载过来后再去读配置文件,这样感觉有点不灵活,于是自己写了一个HTTP下载工具,这样在获取配置文件内容时比较灵活,可以无缝加载配置文件,而不需要重启服务,以下程序摘录自代码中的完整示例代码,示例代码没有做什么异常处理,大家如果使用的话可以把它更加完善一下,http_client.c全文如下- /**************************************************************
- * Copyright (C) 2014-2014 All rights reserved.
- * @Version: 1.0
- * @Created: 2015-4-12 08:38:58
- * @Author: Muyun Www.Mu-Yun.Com
- * @Description: http客户端程序,用于向WEB服务器发起http请求,将返回
- * 结果写入文件
- * @History:
- **************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <errno.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <limits.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-
- FILE *gFile;
-
- /**
- * [url=home.php?mod=space&uid=190858]@brief[/url] http_string_strchr 搜索字符串右边起的第一个匹配字符
- *
- * @Param: s 原始字符串
- * @Param: x 待匹配的字符
- *
- * Returns: 索到即返回x对应的值,否则返回0
- */
- char* http_string_strchr(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;
- }
-
- /**
- * @brief http_string_lower 字符串转换为全小写
- *
- * @Param: s 原始字符串
- */
- void http_string_lower(char* s)
- {
- char *p = s;
-
- while(*p && *p!='\0' )
- {
- if(*p > 'A' && *p < 'Z')
- *p = *p + 32;
- p++;
- }
- }
-
- /**
- * @brief http_gethost_info 字符串src中分析出网站地址和端口,并得到用户要下载的文件
- *
- * @Param: src 输入字符串
- * @Param: web WEB地址
- * @Param: file 需要下载的文件
- * @Param: port WEB端口号,默认为80
- */
- void http_gethost_info(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;
- }
- }
-
- /**
- * @brief http_open_file
- *
- * @Param: file_path
- *
- * Returns:
- */
- FILE *http_open_file(char *file_path)
- {
- gFile = fopen(file_path,"a+");
- return gFile;
- }
- /**
- * @brief http_file_exsits 判断文件是否存在
- *
- * @Param: path 文件路径
- *
- * Returns: 存在返回true,不存在返回false
- */
- int http_file_exsits(const char *path)
- {
- struct stat statbuf;
- if(lstat(path, &statbuf) ==0)
- return S_ISREG(statbuf.st_mode) != 0;//判断文件是否为常规文件
- return 0;
- }
- /**
- * @brief http_socket_init 初始化套接字
- *
- * @Param: port
- * @Param: host_addr
- *
- * Returns: 返回套接字描述符
- */
- int http_socket_init(int port, char *host_addr)
- {
- struct sockaddr_in server_addr;
- struct hostent *host;
- int sockfd;
-
- if((host=gethostbyname(host_addr)) == NULL)/*取得主机IP地址*/
- {
- fprintf(stderr, "Gethostname error, %s\n ", strerror(errno));
- return -1;
- }
- /* 客户程序开始建立 sockfd描述符 */
- if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1)/*建立SOCKET连接*/
- {
- fprintf(stderr, "Socket Error:%s\a\n ",strerror(errno));
- return -1;
- }
-
- /* 客户程序填充服务端的资料 */
- bzero(&server_addr,sizeof(server_addr));
- server_addr.sin_family=AF_INET;
- server_addr.sin_port=htons(port);
- server_addr.sin_addr=*((struct in_addr*)host->h_addr);
-
- /* 客户程序发起连接请求 */
- if(connect(sockfd, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr)) == -1)/*连接网站*/
- {
- fprintf(stderr, "Connect Error:%s\a\n ",strerror(errno));
- return -1;
- }
- return sockfd;
- }
- /*********************************************************************
- *filename: httpclient.c
- *purpose: HTTP协议客户端程序,可以用来下载网页
- *********************************************************************/
- int main(int argc, char *argv[])
- {
- int sockfd = 0;
- char buffer[1024] = "";
- int port = 0;
- int nbytes = 0;
- char host_file[1024] = "";
- char host_addr[256] = "";
- char request[1024] = "";
- int send = 0;
- int totalsend = 0;
- int i = 0;
- FILE *file_fd;
- char *pt;
- char psave[4096];
- char *file_name;
- size_t index = 0;
-
- if(argc < 2)
- {
- fprintf(stderr, "Usage:%s [web-address] [file path]\n ",argv[0]);
- exit(1);
- }
- printf( "parameter.1 is: %s\n ", argv[1]);
-
- http_gethost_info(argv[1], host_addr, host_file, &port);/*分析网址、端口、文件名等*/
- printf( "webhost:%s\n ", host_addr);
- printf( "hostfile:%s\n ", host_file);
- printf( "port:%d\n\n ", port);
-
- file_name = argv[2];
- if(! file_name)
- file_name = host_file;
- sockfd = http_socket_init(port, host_addr);
-
- 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: Close\r\n\r\n ", host_file, host_addr, port);
-
- printf( "%s\n", request);/*准备request,将要发送给主机*/
-
- /*取得真实的文件名*/
- if(*host_file)
- {
- pt = http_string_strchr(host_file, '/');
- }
- else
- {
- pt = 0;
- }
-
- /*发送http请求request*/
- send = 0;
- totalsend = 0;
- nbytes=strlen(request);
- while(totalsend < nbytes)
- {
- send = write(sockfd, request+totalsend, nbytes-totalsend);
- if(send == -1)
- {
- printf( "send error!%s\n ", strerror(errno));
- exit(0);
- }
- totalsend += send;
- printf("%d bytes send OK!\n ", totalsend);
- }
- /*请求结束,等待响应*/
-
- /*将结果写回到文件*/
- if(http_file_exsits(file_name) )
- {
- remove(file_name);
- }
- file_fd = http_open_file(file_name);
- if(file_fd == NULL)
- {
- perror("Open file error!\n");
- return -1;
- }
-
- i=0;
- /*连接成功了,接收http响应,每次处理4096个字节*/
- memset(psave,0,4096);
- while((nbytes=read(sockfd,buffer,1))==1)
- {
- if(i < 4)
- {
- /*这里处理http头部*/
- if(buffer[0] == '\r' || buffer[0] == '\n')
- {
- i++;
- }
- else
- {
- i = 0;
- }
- printf( "%c", buffer[0]);/*把http头信息打印在屏幕上*/
- }
- else /*如果结尾部分不为\r\n\r\n则表示头接收完毕,下面是请求内容*/
- {
- psave[index++] = buffer[0];
- if(index > 4096)
- {
- fwrite(psave,4096,1,file_fd);
- fflush(file_fd);
- memset(psave,0,4096);
- index = 0;
- }
-
- }
- }
- /*将剩余的字符写入文件*/
- if(index <= 4096)
- {
- fwrite(psave,index,1,file_fd);
- fflush(file_fd);
- }
- close(sockfd);
- fclose(file_fd);
- return 0;
- }
复制代码
编译:gcc http_client.c -o http_client
运行:./http_client http://192.168.1.1/sql.conf
也可以这样运行./http_client 192.168.1.1/sql.conf /tmp/sql.conf 后面的参数为指定文件存储位置。
这样就会把远程服务器上的文件下载过来了。
|
|