//==========================================================
//文件名称:senddata.c
//功能描述:实现客服端信息的预处理,与数据发送
//包含文件:senddata.h
//维护日期:
//===========================================================
#include "senddata.h" char request_file[100]; //===================================================================================
//函数名称:get_client_request(int connfd,char *request)
//功能描述:读取client段的请求报文,并获得报文的第一行
//函数参数:connfd 接收到的client端的socket文件描述符,request 保存报文第一行的指针变量
//返回值: 无
//=====================================================================================
void get_client_request(int connfd,char *request) { char recvbuf[4096]; char *pos; memset(recvbuf,0,sizeof(recvbuf)); if(read(connfd,recvbuf,sizeof(recvbuf))<=0) { exit(0); } if((pos=strstr(recvbuf,"\n"))!=NULL) { *pos='\0'; } strcpy(request,recvbuf); } //============================================================================
//函数名称:file_is_found
//功能描述:查找当前目录下,文件是否为请求文件,此函数为ftw函数服务的被动型函数
//函数参数:cur_path ftw函数存放当前路径的指针变量,file_stat ftw存放文件信息的
// 文件状态结构体指针,falg ftw存放文件类型的整形变量
//返回值: int找到文件返回1,没找到返回0
//===========================================================================
int file_is_found(char *cur_path,struct stat *file_stat,int flag) { if(flag==FTW_F) { if(strcmp( cur_path+(strlen(cur_path)-strlen(request_file)),request_file)==0 ) { //printf("in 20 file=%s\n",cur_path);
strcpy(request_file,cur_path); return 1; } } return 0;
} //===================================================================
//函数名称:serv_resource_find
//功能描述:遍历server当前路径下的所有目录,寻找client请求的资源文件,
// 并将文件大小保存到指针变量file_size中
//函数参数:serv_resource_path资源搜索路径指针,保存文件大小的指针变量
//返回值: int,找到请求文件返回1,没找到返回0;
//======================================================================
int serv_resource_find(char *serv_resource_path,off_t *file_size) { int ret=0; struct stat file_stat; ret=ftw(serv_resource_path,(int (*)())file_is_found,2);//遍历目录树,参考unix函数手册
if(ret==1) { *file_size=file_stat.st_size; return 1; } else { return 0; } } //====================================================================================
//函数名称:send_data
//功能描述:根据client_info的内容分析报文格式,并发送数据
//函数参数:connfd 已连接到的客服端socket文件描述符,client_info报文第一行内容指针变量
//返回值: 无
//====================================================================================
void send_data(int connfd,char *client_info) { char *resp_head = "HTTP/1.1 200 OK\r\n" \ "Content-Type: text/html\r\n" \ "Content-Length:%ld\r\n" \ "\r\n"; char *not_found = "HTTP/1.1 404 Not Found\r\n" \ "Content-Type: text/html\r\n" \ "Content-Length: 40\r\n" \ "\r\n" \ "File not found
"; char *bad_request = "HTTP/1.1 400 Bad Request\r\n" \ "Content-Type: text/html\r\n" \ "Content-Length: 39\r\n" \ "\r\n" \ "Bad Request (Invalid Hostname)"; char *moved_permanently = "HTTP/1.1 301 Moved Permanently\r\n"\ "Content-Length: 147\r\n" \ "Content-Type: text/html\r\n" \ "Location: %s\r\n" \ "\r\n" \ "Document MovedObject MovedThis document may be found here"; char *cli_info_arg[5]; char temp[30]; char buf[2048]; char respbuf[1024]; int cli_fd; unsigned long int file_lenth=0; memset(temp,0,sizeof(temp)); memset(request_file,0,sizeof(request_file)); splitinfo(client_info," ",cli_info_arg);//分割信息得到客户端要访问的文件名
strcpy(request_file,cli_info_arg[1]); strcpy(temp,cli_info_arg[1]); temp[0]='\0'; if(!strcmp(request_file,"/")) { strcpy(request_file,"index.htm"); } else //去掉文件前的"/"
{ strcpy(request_file,temp+1); } //==========判断当前路径是否有client要访问的文件
//if(access(cli_file,F_OK)==0)
off_t file_size; //if(serv_resource_find(cli_file,&file_size))
if(serv_resource_find("./",&file_size)) { //char *fp=cli_file;
//struct stat request_file;
//stat(fp,&request_file);
//-------发送应答报头
//sprintf(respbuf,resp_head,request_file.st_size);
sprintf(respbuf,resp_head,file_size); write(connfd,respbuf,strlen(respbuf)); //-------用fprintf类的函数式,因为f*类函数是带有缓冲,所以必须用fflush才能使数据从缓冲区输出。
//FILE *newfp = fdopen(connfd, "w");//相当于把整数文件描述符,转换为文件指针
//fprintf(newfp, resp_head, len);
//fflush(newfp);
memset(buf,0,sizeof(buf)); if((cli_fd=open(request_file,O_RDONLY))<0) { perror("can not open file in send_data()\n"); exit(0); } int len; while((len = read(cli_fd,buf,sizeof(buf)))>0) { //printf("%s",buf);
write(connfd,buf,len); memset(buf,0,sizeof(buf)); } close(cli_fd); } else { printf("in is not!\n"); write(connfd,not_found,strlen(not_found)); } }
|