/**************************************************************************************/
/*文件:rw.c */
/*简介:自定义I/O函数实现文件。 */
/*************************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "rw.h"
/*read()函数的扩展,解决读不全的问题*/
ssize_t readall(int fd, void* buf,size_t *len)
{
size_t nleft;
ssize_t nread;
ssize_t total;
char *ptr;
ptr = buf;
nleft = *len;
total = 0;
/*反复读,直到没有新的数据可读*/
while( nleft > 0)
{
if((nread = read(fd,ptr,*len)) == -1)
{
perror("readall");
break;
}
if(nread ==0)
break;
nleft -= nread;
ptr += nread;
total += nread;
*len = nleft;
}
*len = total;
return (nread==-1)?-1:0;
}
/*write()函数的扩展,解决写不够的问题*/
ssize_t writeall(int fd, void* buf,size_t *len)
{
size_t nleft;
ssize_t nwrite;
ssize_t total;
const char *ptr;
ptr = buf;
nleft = *len;
total = 0;
/*反复写,直到所有的数据都写入*/
while( nleft > 0)
{
if((nwrite = write(fd,ptr,*len))== -1)
{
perror("write all");
break;
}
nleft -= nwrite;
ptr += nwrite;
total += nwrite;
*len = nleft;
}
*len = total;
return (nwrite==-1)?-1:0;
}
/*分析客户端的命令,提取出请求的文件名*/
int read_cmd(int sockfd,char* cmd_buf,int len)
{
char line[MAX_LEN];
int my_len = 0;
int total_len =0;
char *ptr;
int can_read;
if(len > MAX_LEN)
len = MAX_LEN;
can_read = 1;
strcpy(cmd_buf,"\0");
while(can_read)
{
if((my_len = read(sockfd, line,len))<0 )
{
perror("read");
return -1;
}
total_len += my_len;
if(total_len > len)
{
printf("Recieve command error!\n");
return -1;
}
if((ptr=strstr(line,"\r\n"))==NULL)
{
if(total_len <= len)
strcat(cmd_buf, line);
}
else
{
strncat(cmd_buf,line,ptr-line);
can_read = 0;
}
printf("Client requests file: %s\n",cmd_buf);
}
return 0;
}
/*发送文件至客户端*/
int send_file(int sockfd,char *file_name)
{
int file_fd;
int file_size;
int read_left;
int len;
int error_flag;
int readlen;
struct stat file_state;
char buffer[MAX_LEN];
int dot_number = 0;
if((file_fd = open(file_name,O_RDONLY)) == -1)
{
perror("open");
return -1;
}
if(fstat(file_fd, &file_state)==-1)
{
perror("fstat");
return -1;
}
file_size = file_state.st_size;
read_left = file_size;
len = MAX_LEN;
while(read_left > 0)
{
/* now read the file */
readlen = MAX_LEN;
error_flag = readall(file_fd,buffer,&readlen);
if(error_flag<0 )
{
return -1;
}
read_left -= readlen;
len = readlen;
error_flag = writeall(sockfd,buffer,&len);
if(error_flag == -1)
return -1;
if(readlen==0 && read_left!=0)
{
printf("the file is not read fully!\n");
return -1;
}
if(read_left==0)
{
printf("\nServer sent file over!\n");
}
}
close(file_fd);
return 0;
}