我在客户端/服务器程序上工作,客户端发送/接收文件。文件可以是文本文件或二进制文件。但是,我不确定我需要做出哪些更改(如果有)以适应任一文件类型。基本上我希望读取/写入服务器端的文件而不关心它是什么类型的文件,我希望能够这样做而不检查它是什么类型的文件。这样的代码会起作用吗?为什么或为什么不呢?
服务器代码段:
//CREATING/WRITING TO A FILE
//we are ready to begin reading data from the client, and storing it
int fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
while(nbytes < bytes)
{
//only read the neccessary # of bytes: the remaining bytes vs max buffer size
int min_buffer = (bytes - nbytes) < BUFFER_SIZE ? (bytes - nbytes) : BUFFER_SIZE;
length = recv( client->client_socket, contents, min_buffer, 0);
if(fd < 0) //the fd is bad, but we need to continue reading bytes anyway
{
nbytes += length;
continue;
}
if(length <= 0)
break;//string empty or error occurred...this error means the client closed?
if(write(fd, contents, min_buffer) != min_buffer)
{
//printf("There was an error writing to the file.\n");
}
else
{
nbytes += length;
}
}
//READING A STORED FILE AND SENDING THE DATA TO CLIENT
int fd = open(pathname, O_RDWR, S_IRUSR | S_IWUSR);
if(fd >= 0)
{
while(bytes > 0)
{
bytes = read(fd, buffer, BUFFER_SIZE );
if(bytes > 0)//we have read some bytes
{
//send the client the data
write(client->client_socket, buffer, bytes);
}
else if(bytes < 0)
{
//some error occured
write( client->client_socket, "ERROR: Could not read\n", 22);
return;
}
}
}
因此,如果客户端发送二进制文件与文本文件,那么此代码会导致问题吗? (我们可以假设客户端知道期望的文件类型。)
注意:关于这一点的另一个令人困惑的细节是,在c中编写/读取二进制文件的教程似乎与常规文件没有任何真正的区别,这就是我在这里的原因。
答案 0 :(得分:2)
只需使用“二进制”文件即可。 Linux在OS级别的文件中“text”和“binary”之间没有区别,只有文件中包含字节。 IE浏览器。期望文件包含每个可能的字节值,而不是为不同类型的内容编写不同的代码。
Windows存在差异:Windows中的文本模式意味着在写入/读取文件时,程序中的换行符(\n
)会转换为\r\n
。以二进制模式读取的书面文本文件将包含这两个字节而不是原始\n
,反之亦然。 (此外,MS在文档中并不十分清楚,这是唯一的区别,它可以轻松地混淆初学者。)
如果您使用标准C fopen
和fclose
而不是特定于Linux的open
等,则可以指定以二进制或文本模式打开文件(在Linux上也是如此)。这是因为带有fopen的代码应该可以在Windows和Linux上运行而不需要任何特定于操作系统的更改;但是你在fopen中选择的东西在Linux上运行时无关紧要(可以通过阅读fopen等源代码来验证)
关于插座:
Linux:没有区别(再次)
Windows:没有区别。只有字节,没有奇怪的换行符。
答案 1 :(得分:-1)
由于二进制/文本文件问题,我将头发撕了一天。我将二进制数据输出到“文件”(显然是文本文件,……经过多年的C工作,我一直认为文件是文件),并不断在输出中插入虚假字符。我什至下载了一个新的编译器,但是遇到了同样的问题。问题?当我使用任何fprint系列语句输出十六进制A时,将插入十六进制D。是的,换行符-A-已由回车/换行符DA代替。根据不同系统的开发方式,这是一个遗留的“行尾”问题。发现问题的难点在于,意识到A不仅被解释为二进制字段,而且实际上被识别为换行符。