我想实现一个程序,将任何文件从服务器传输到客户端。我必须使用读/写函数来读写数据(用于学校作业)。这是服务器和客户端的代码。
server.c
char buffer[512];
if( (file = open(strTable[1], O_RDONLY)) == -1 ) { perror("Open"); }
while( read(file, buffer, sizeof(buffer)) != 0 )
{
size = strlen(buffer)+1;
if( write(newsock, &size, sizeof(size)) < 0 ) { perror("Write"); exit(1); }
write_all(newsock, buffer, strlen(buffer)+1);
}
size = 4;
if( write(newsock, &size, sizeof(size)) < 0 ) { perror("Write"); exit(1); }
write_all(newsock, "end", 4);
它打开strTable [1](包含我想要读取的文件)它读取sizeof(缓冲区)字节,然后我发送给客户端我将写入多少字节,然后发送字节。这是write_all函数。
int write_all(int sock, char* buffer, int size)
{
int nwrite, sent = 0;
while( sent < size )
{
if( (nwrite = write(sock, buffer + sent, size - sent)) < 0 )
{ perror("Write"); exit(1); }
sent += nwrite;
}
return sent;
}
client.c
if( (file = open(absolute, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1 )
{ perror("Open"); }
while( true )
{
received = 0;
/* Read the desired readable size */
if( read(sock, &size, sizeof(size)) < 0 )
{ perror("Read"); pthread_exit(NULL); }
/* Read all data */
while( received < size )
{
if( (nread = read(sock, buffer + received, size - received)) < 0 )
{ perror("Read"); pthread_exit(NULL); }
received += nread;
}
if( strncmp(buffer, "end", 4) == 0 ) { break; }
write_all(file, buffer, strlen(buffer)+1);
}
客户端打开一个文件(绝对值)并在其中写入读取的内容。它首先读取它必须读取的大小,然后它不会停止读取,直到达到该大小。如果客户端读取&#34;结束&#34;然后服务器停止写入套接字,以便客户端停止读取。
问题是我无法在转移后打开文件。我读了一些我无法打开的图片。我也读了一个file.txt,我写了一些随机的单词,这似乎是正确的复制,但它也有一些垃圾(它的照片编号2)。为什么我得到这个以及如何正确地从套接字传输文件?
答案 0 :(得分:1)
常见问题。 read()
不会终止缓冲区,因此在其上使用strlen()
作为计数无效。读/写循环应如下所示:
int count;
while ((count = read(inFD, buffer, sizeof buffer)) > 0)
{
if (write(outFD, buffer, count) < 0)
{
perrror("write"); // at least
break;
}
}
然后进行错误处理,如下所示:
if (count < 0)
{
perror("read"); // at least
}
您的第二个问题是假设"end"
本身将作为单独的消息收到。无法保证这一点。您将必须通过在每个文件之后关闭套接字来使用流结束,或者在每个文件之前发送长度,并且仅从流中为每个文件读取那么多字节。但是,由于您已经发送了长度,因此无论如何发送"end"
都是毫无意义的。