在下面的代码中,我尝试从套接字read
并将结果存储在一个文件中。
实际发生的是,我的客户端向我的服务器发送了一个file.html
的GET请求。我的服务器找到该文件并将其内容写入套接字。最后,我的客户端从thread_fd读取内容并重新创建文件。
由于某种原因,重新创建的文件的内容比原始文件少。我把问题定位到最后的一些行,这是缺失的。当我在printf("%s", buffer)
循环中使用while
时,STDOUT
中的所有内容似乎都很好,但fprintf
对于81.000字节大小的文件错过了一些3.000字节。
#define MAXSIZE 1000
int bytes_read, thread_fd;
char buffer[MAXSIZE];
FILE* new_file;
memset(buffer, 0, MAXSIZE);
if((new_file = fopen(path, "wb+")) == NULL)
{
printf("can not open file \n");
exit(EXIT_FAILURE);
}
while ((bytes_read = read(thread_fd, buffer, MAXSIZE)) > 0)
{
fprintf(new_file, "%s", buffer);
if(bytes_read < MAXSIZE)
break;
memset(buffer, 0, MAXSIZE);
}
答案 0 :(得分:1)
您从套接字读取的二进制数据可能包含也可能不包含\ 0字节。当你然后fprintf那个数据时,fprintf会在它遇到的第一个\ 0处停止。在你的情况下,这是完整文件的3000字节。如果您的文件不包含\ 0字节,则fprintf将继续打印ram内容,直到它出现段错误。
使用write()将数据写回文件并检查错误。不要忘记关闭()文件并检查错误。
答案 1 :(得分:0)
您的代码应该/看起来像:
int readfile(int thread_fd, char *path)
{
unsigned int bytes_read;
char buffer[MAXSIZE];
int new_file;
if ((new_file = open(path, _O_CREAT|_O_BINARY,_S_IWRITE)) == -1) return -1;
while ((bytes_read = read(thread_fd, buffer, MAXSIZE)) > 0)
{
if (write(new_file, buffer, bytes_read)!= bytes_read) {
close(new_file);
return -2;
}
}
close(new_file);
return 0;
}
答案 2 :(得分:0)
您的代码可能会出现一些问题。
最可能的原因是:
if(bytes_read < MAXSIZE)
break;
当read
返回小于请求的字节数时,这将结束循环。然而,这是完全正常的行为,并且可能发生例如。当read
呼叫时没有足够的字节可用时(它毕竟是从网络套接字读取)。只要read
返回值&gt;,就让循环继续。 0
(假设套接字是阻塞套接字 - 如果没有,您还必须检查EAGAIN
和EWOULDBLOCK
)。
此外,如果您接收的文件包含二进制数据,那么使用fprintf
和"%s"
写入目标文件不是一个好主意。一旦找到'\0'
字节(这在二进制数据中并不罕见),它将立即停止写入。请改用fwrite
。
即使您正在接收文字(由html文件扩展名建议),使用fprintf
与"%s"
仍然不是一个好主意,因为收到的数据赢了& #39; t '\0'
终止。
答案 3 :(得分:0)
这很有用!
ps:我不知道我是不是应该这样做,因为我是新来的,但实际上没有理由去消极。任何问题都是一个好问题。如果你知道它就回答它。不要判断它。#define MAXSIZE 1000
int bytes_read, thread_fd, new_file;
char buffer[MAXSIZE];
memset(buffer, 0, MAXSIZE);
if((new_file = open(path, O_RDONLY | O_WRONLY | O_CREAT)) < 0)
{
printf("can not open file \n");
exit(EXIT_FAILURE);
}
while ((bytes_read = read(thread_fd, buffer, MAXSIZE)) > 0)
write(new_file, buffer, bytes_read);
close(new_file);