分享
 
 
 

linux下的应用开发起步--简化蚂蚁制作(二)

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

linuxbird

3.ok,在初步了解完这些系统调用后,我们就可以开始干活了。

A.开始定义头文件了。

#ifndef __ANT_H

#define __ANT_H

//定义包含库

#include

#include

#include

#include

#include

#include

#include

#include

#include

//定义蚂蚁的最大数目

#define MAXANTNUM 6

//定义缓存大小

#define BUFSIZE 1500

//从传进来的长字符串分别拣开文件名、域名、路径、端口等

#define FILENAME 1

#define SITENAME 2

#define PATHNAME 3

#define PORTNAME 4

typedef char URL[256];

//定义蚂蚁的数据结构

struct Ant{

int s;

// URL mission;

int position;

int amount;

char haversack[BUFSIZE];

int ready;

};

//定义任务的数据结构

struct Mission{

char host[100];

u_short port;

URL url;

};

//是否用代理 0表示不用,1表示用

extern int use_proxy;

//代理地址

extern char proxy_server[100];

//代理端口

extern u_short proxy_port;

//蚂蚁数目

extern int ant_num;

extern int bulk;

//下载进度

extern int progress;

//配置文件

extern char cfgfile[256];

//日志文件

extern char logfile[256];

extern struct Ant* ants[10];

extern struct Mission ms;

//此函数是读取配置文件的

extern void read_cfg(char* file);

//此函数是初始化环境的,给变量赋值

extern void init_env();

//分配下载任务

extern int assign_mission(FILE* log, struct Ant* ant);

//此函数是去掉字符串的空格

extern void eat_whitespace(char* str);

//

extern char* extract_from_url(URL url,int what);

//从日志文件中取得地址

extern char* get_url_from_log(FILE* log);

//返回下载文件的大小

extern int get_size_of_url(struct Mission* pms);

//go......下载文件

extern int go(struct Ant* ant, struct Mission* pms);

extern void enroll(struct Ant* ant, fd_set* rset);

extern void unenroll(struct Ant* ant,fd_set* rset);

extern int receive(struct Ant* ant, FILE* save);

//如果意外退出,保存当前状态

extern int save_status(struct Ant* ant, FILE* log);

#endif

B.在定义完头文件后,下面就可以写辅助函数了,主要是围绕着读取配置、创建连接、下载文件、保存文件、保存当前蚂蚁状态等。

下面就是funcs.c[url=http://www.pccode.net].net" class="wordstyle"源码内容

#include "ant.h"

//读取配置文件,并赋予相关变量的值

void

read_cfg(char* cfgfile)

{

FILE* f;

int i;

char line[256];

char* p=(char*)NULL;

//判断是否能打开该文件

if((f = fopen(cfgfile, "r")) == (FILE*)NULL){

printf("can not open cfg file

");

exit(1);

}

while(fgets(line, 256, f)!=(char*)NULL){

eat_whitespace(line);//去掉空行(此喂自定义函数)

if(line[0]=='#')

continue;

for(i = 0; line[i]; i++)

line[i]=tolower(line[i]); //将所有字母转换成小写的

if((p = strstr(line,"use_proxy"))){ //查找代理(proxy)开关设置信息,有则给use_proxy=1,否则为0

if(strstr(line,"yes"))

use_proxy=1;

else

use_proxy=0;

}

else if((p = strstr(line,"proxy_server"))){ //查找代理服务器地址设置信息,将值赋给(proxy_server)

p=strstr(line,"=");

eat_whitespace(++p);

strcpy(proxy_server, p);

}

else if((p = strstr(line, "proxy_port"))){ //查找代理端口设置信息,将值赋给(proxy_port)

p=strstr(line, "=");

eat_whitespace(++p);

proxy_port=atoi(p);

}

}

}

void

//初始化环境参数,将值赋给各个变量

init_env( )

{

strcpy(cfgfile, "./ant.conf");

//取得配置文件名

read_cfg(cfgfile);

//取得配置文件中的变量

logfile[0] = cfgfile[0] = 0;

ant_num = MAXANTNUM;

bulk = 0; progress=0;

}

char*

//从记录文件里取得URL地址,断点续传的时候用,函数返回url

get_url_from_log(FILE* log)

{

static URL url;

URL line;

fseek(log, 0, SEEK_SET);

//从文件中读取字符串,从起始字符为"#"的行取url

while(fgets(line, sizeof(line)-1, log)!=(char*)NULL){

eat_whitespace(line);

if(line[0]=='#')

continue;

strcpy(url, line);

return url;

}

memset(url,0,sizeof(url));

//内存中为之分配地址

return url;

}

int

//分配下载任务,失败返回0,从上面函数返回的字符中分析出将相关的值赋给数据结构ant

assign_mission(FILE* log, struct Ant* ant)

{

char line[256];

char* p;

while(fgets(line, 256, log)!=(char*)NULL){

eat_whitespace(line);

if((line[0]=='#')||toupper(line[0]=='H')||toupper(line[0]=='F'))

continue;

if(isdigit(line[0])){

ant->position=atoi(line);

p=index(line,':');

ant->amount=atoi(++p);

return 1;

}else

continue;

}

return 0;

}

void

//去掉字符流中的空行

eat_whitespace(char* str)

{

char* p;

int i;

p=str;

for(i=0; isspace(p[i]); i++ );

for( ;*p ;p++)

*p=p[i];

p=str;

for(i=strlen(str)-1;isspace(p[i]);i--)

p[i]=0;

}

char*

//从传进来的url字符串中,分析出文件名、域名、端口名、路径,根据不同的what返回不同的字串。

extract_from_url(URL url,int what)

{

static char res[100];

char* p;

char* pn;

res[0]=0;

memset(res,0,100);

switch (what){

case FILENAME://分析文件名、若没有用index.html替代(网络默认的首页,呵呵)

p=rindex(url,'/');

if((*(p-1)=='/')||(*(p+1)==0))

strcpy(res,"index.html");

else

strcpy(res,++p);

break;

case PATHNAME:

break;

case SITENAME: //分析出域名,其中,对ftp,和http做出分类

if((p=index(url, '@')))

p++;

else{

if((p=strstr(url,"http://")))

p+=7;

else if((p=strstr(url,"ftp://")))

p+=6;

else

p=url;

}

if((pn=index(p,':'))||(pn=index(p,'/'))){

strncpy(res,p,pn-p);

res[pn-p] = 0;

}

else

strcpy(res,p);

break;

case PORTNAME: //在字符"www.XXXX.com:8080/"之间取得端口号

if((p=rindex(url,':'))&&(*(++p)!='/')){

if((pn=index(p,'/'))){

strncpy(res,p,pn-p);

res[pn-p]=0;

}

else

strcpy(res,p);

}

else{

strcpy(res,"80");

}

break;

}

return res;

}

//

int

//根据传进来的Mission数据结构,建立socket链接,取得文件的大小。

get_size_of_url(struct Mission* pms)

{

int s;

struct sockaddr_in sin;

struct hostent* phe;

char cmd[256];

char msg_hdr[1000];

char* p;

//准备http中GET 方法的请求。

sprintf(cmd,"GET %s HTTP/1.0

", pms->url);

//创建socket

if((s=socket(PF_INET,SOCK_STREAM,0))<0)

return -1;

//取得远程主机的IP地址,失败函数返回-1

if((phe = gethostbyname(pms->host)) == NULL)

return -1;

memset(&sin,0,sizeof(sin));

memcpy(&sin.sin_addr,phe->h_addr,sizeof(struct in_addr));

sin.sin_family=AF_INET;

sin.sin_port=htons(pms->port);

//跟远程机器建立连接,失败函数返回-1

if(connect(s,(struct sockaddr*)&sin,sizeof(sin))==-1)

return -1;

//发送GET请求

if(write(s,cmd,strlen(cmd))<0)

return 0;

//从链接描述符(连接管道)中读取传送过来的数据

if(read(s, msg_hdr, 300)<0)

return 0;

close(s);

printf("%s",msg_hdr);

//读到该文件的大小

if((p=strstr(msg_hdr,"Content-Length"))||(p=strstr(msg_hdr,"Content-length:")))

p+=16;

else

return 0;

//返回大小

return atoi(p);

}

//根据传进来的 ant、mission数据结构,开始下载数据。

int

go(struct Ant* ant, struct Mission* pms)

{

struct sockaddr_in sin;

struct hostent* phe;

char cmd[256];

//准备请求的GET字符

if(ant_num==1)

sprintf(cmd,"GET %s HTTP/1.0

", pms->url);

sprintf(cmd,"GET %s HTTP/1.0

Range: bytes=%d-%d

Cache-Control: no-cache

", pms->url,ant->position, ant->position+ant->amount-1);

//为ant数据结构创建套接口

if((ant->s=socket(PF_INET,SOCK_STREAM,0))<0)

return 0;

//取得远程主机的IP地址,失败返回0

if((phe = gethostbyname(pms->host)) == NULL)

return 0;

memset(&sin,0,sizeof(sin));

memcpy(&sin.sin_addr,phe->h_addr,sizeof(struct in_addr));

sin.sin_family=AF_INET;

sin.sin_port=htons(pms->port);

//建立连接

if(connect(ant->s,(struct sockaddr*)&sin,sizeof(sin))==-1)

return 0;

//发送读取请求

if(write(ant->s,cmd,strlen(cmd))<0)

return 0;

printf("Connect Host:%s , port:%d

",pms->host,pms->port);

printf("%s",cmd);

return 1;

}

void

enroll(struct Ant* ant, fd_set* rset)

{

FD_SET(ant->s,rset);

}

void

unenroll(struct Ant* ant, fd_set* rset)

{

FD_CLR(ant->s,rset);

}

int

//把传进来的数据结构ant的数据存储起来

receive(struct Ant* ant, FILE* save)

{

int as;

int length;

char* p;

if((length = read(ant->s, ant->haversack, BUFSIZE)) >= 0){

p=ant->haversack;

if(!ant->ready){

ant->ready=1;

p=strstr(ant->haversack, "

");

p+=4;

length-=(p-ant->haversack);

}

}

else{

return 0;

}

if(0 == fseek(save, ant->position, SEEK_SET)){

if(0 <= fwrite(p, sizeof(char), length, save)){

ant->amount-=length;

ant->position+=length;

return length;

}

}

return 0;

}

int

//保存当前的蚂蚁数目,以及状态

save_status(struct Ant* ant, FILE* log)

{

return fprintf(log

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有